github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/network/p2p/builder/resourceLimit.go (about)

     1  package p2pbuilder
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/libp2p/go-libp2p"
     7  	rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager"
     8  	"github.com/rs/zerolog"
     9  
    10  	p2pconfig "github.com/onflow/flow-go/network/p2p/config"
    11  )
    12  
    13  // BuildLibp2pResourceManagerLimits builds the resource manager limits for the libp2p node.
    14  // Args:
    15  //
    16  //	logger: logger to log the resource manager limits.
    17  //	config: the resource manager configuration.
    18  //
    19  // Returns:
    20  //
    21  //   - the resource manager limits.
    22  //   - any error encountered, all returned errors are irrecoverable (we cannot continue without the resource manager limits).
    23  func BuildLibp2pResourceManagerLimits(logger zerolog.Logger, config *p2pconfig.ResourceManagerConfig) (*rcmgr.ConcreteLimitConfig, error) {
    24  	defaultLimits := rcmgr.DefaultLimits
    25  	libp2p.SetDefaultServiceLimits(&defaultLimits)
    26  
    27  	mem, err := allowedMemory(config.MemoryLimitRatio)
    28  	if err != nil {
    29  		return nil, fmt.Errorf("could not get allowed memory: %w", err)
    30  	}
    31  	fd, err := allowedFileDescriptors(config.FileDescriptorsRatio)
    32  	if err != nil {
    33  		return nil, fmt.Errorf("could not get allowed file descriptors: %w", err)
    34  	}
    35  
    36  	scaled := defaultLimits.Scale(mem, fd)
    37  	scaledP := scaled.ToPartialLimitConfig()
    38  	override := rcmgr.PartialLimitConfig{}
    39  	override.System = ApplyResourceLimitOverride(logger, p2pconfig.ResourceScopeSystem, scaledP.System, config.Override.System)
    40  	override.Transient = ApplyResourceLimitOverride(logger, p2pconfig.ResourceScopeTransient, scaledP.Transient, config.Override.Transient)
    41  	override.ProtocolDefault = ApplyResourceLimitOverride(logger, p2pconfig.ResourceScopeProtocol, scaledP.ProtocolDefault, config.Override.Protocol)
    42  	override.PeerDefault = ApplyResourceLimitOverride(logger, p2pconfig.ResourceScopePeer, scaledP.PeerDefault, config.Override.Peer)
    43  	override.ProtocolPeerDefault = ApplyResourceLimitOverride(logger, p2pconfig.ResourceScopePeerProtocol, scaledP.ProtocolPeerDefault, config.Override.PeerProtocol)
    44  
    45  	limits := override.Build(scaled)
    46  	logger.Info().
    47  		Str("key", keyResourceManagerLimit).
    48  		Int64("allowed_memory", mem).
    49  		Int("allowed_file_descriptors", fd).
    50  		Msg("allowed memory and file descriptors are fetched from the system")
    51  	newLimitConfigLogger(logger.With().Str("key", keyResourceManagerLimit).Logger()).LogResourceManagerLimits(limits)
    52  	return &limits, nil
    53  }
    54  
    55  // ApplyResourceLimitOverride applies the override limit to the original limit.
    56  // For any attribute that is set in the override limit, the original limit will be overridden, otherwise
    57  // the original limit will be used.
    58  // Args:
    59  //
    60  //		logger: logger to log the override limit.
    61  //		resourceScope: the scope of the resource, e.g., system, transient, protocol, peer, peer-protocol.
    62  //		original: the original limit.
    63  //	 override: the override limit.
    64  //
    65  // Returns:
    66  //
    67  //	the overridden limit.
    68  func ApplyResourceLimitOverride(logger zerolog.Logger,
    69  	resourceScope p2pconfig.ResourceScope,
    70  	original rcmgr.ResourceLimits,
    71  	override p2pconfig.ResourceManagerOverrideLimit) rcmgr.ResourceLimits {
    72  	lg := logger.With().Logger()
    73  
    74  	if override.StreamsInbound > 0 {
    75  		lg = lg.With().Int("streams-inbound-override", override.StreamsInbound).Int("streams-inbound-original", int(original.StreamsInbound)).Logger()
    76  		original.StreamsInbound = rcmgr.LimitVal(override.StreamsInbound)
    77  	}
    78  
    79  	if override.StreamsOutbound > 0 {
    80  		lg = lg.With().Int("streams-outbound-override", override.StreamsOutbound).Int("streams-outbound-original", int(original.StreamsOutbound)).Logger()
    81  		original.StreamsOutbound = rcmgr.LimitVal(override.StreamsOutbound)
    82  	}
    83  
    84  	if override.ConnectionsInbound > 0 {
    85  		lg = lg.With().Int("connections-inbound-override", override.ConnectionsInbound).Int("connections-inbound-original", int(original.ConnsInbound)).Logger()
    86  		original.ConnsInbound = rcmgr.LimitVal(override.ConnectionsInbound)
    87  	}
    88  
    89  	if override.ConnectionsOutbound > 0 {
    90  		lg = lg.With().Int("connections-outbound-override", override.ConnectionsOutbound).Int("connections-outbound-original", int(original.ConnsOutbound)).Logger()
    91  		original.ConnsOutbound = rcmgr.LimitVal(override.ConnectionsOutbound)
    92  	}
    93  
    94  	if override.FD > 0 {
    95  		lg = lg.With().Int("fd-override", override.FD).Int("fd-original", int(original.FD)).Logger()
    96  		original.FD = rcmgr.LimitVal(override.FD)
    97  	}
    98  
    99  	if override.Memory > 0 {
   100  		lg = lg.With().Int("memory-override", override.Memory).Int("memory-original", int(original.Memory)).Logger()
   101  		original.Memory = rcmgr.LimitVal64(override.Memory)
   102  	}
   103  
   104  	lg.Info().Str("scope", resourceScope.String()).Msg("scope resource limits examined for override")
   105  	return original
   106  }