Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Implement ipfs swarm limit [scope] --reset #8950

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions core/commands/swarm.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ const (
swarmStreamsOptionName = "streams"
swarmLatencyOptionName = "latency"
swarmDirectionOptionName = "direction"
swarmResetOptionName = "reset"
)

type peeringResult struct {
Expand Down Expand Up @@ -387,6 +388,9 @@ Changes made via command line are persisted in the Swarm.ResourceMgr.Limits fiel
cmds.StringArg("scope", true, false, "scope of the limit"),
cmds.FileArg("limit.json", false, false, "limits to be set").EnableStdin(),
},
Options: []cmds.Option{
cmds.BoolOption(swarmResetOptionName, "reset resource manager limits to default"),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
node, err := cmdenv.GetNode(env)
if err != nil {
Expand All @@ -397,6 +401,8 @@ Changes made via command line are persisted in the Swarm.ResourceMgr.Limits fiel
return libp2p.NoResourceMgrError
}

reset, _ := req.Options[swarmResetOptionName].(bool)

scope := req.Arguments[0]

// set scope limit to new values (when limit.json is passed as a second arg)
Expand All @@ -418,6 +424,13 @@ Changes made via command line are persisted in the Swarm.ResourceMgr.Limits fiel
}
}

if reset {
err = libp2p.ResetLimit(node.ResourceManager, node.Repo, scope)
if err != nil {
return err
}
}

// get scope limit
result, err := libp2p.NetLimit(node.ResourceManager, scope)
if err != nil {
Expand Down
70 changes: 70 additions & 0 deletions core/node/libp2p/rcmgr.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package libp2p
import (
"context"
"fmt"
"github.com/pbnjay/memory"
"os"
"path/filepath"
"strings"
Expand Down Expand Up @@ -397,3 +398,72 @@ func NetSetLimit(mgr network.ResourceManager, repo repo.Repo, scope string, limi

return nil
}

func ResetLimit(mgr network.ResourceManager, repo repo.Repo, scope string) error {
cfg, err := repo.Config()
if err != nil {
return fmt.Errorf("reading config to set limit: %w", err)
}

// Do not reset if there are no limits or the resource manager is not enabled
if !cfg.Swarm.ResourceMgr.Enabled.WithDefault(true) || cfg.Swarm.ResourceMgr.Limits == nil {
return nil
}

// Retrieve the existing limit!
oldLimit, err := NetLimit(mgr, scope)
if err != nil {
return fmt.Errorf(" error retrieving existing limits: %w", err)
}

getDefaultBasicLimitConfig := func(limit rcmgr.BaseLimit, mem rcmgr.MemoryLimit) rcmgr.BasicLimitConfig {
var result rcmgr.BasicLimitConfig
switch oldLimit.Dynamic {
case true:
result.Dynamic = true
result.MemoryFraction = mem.MemoryFraction
result.MinMemory = mem.MinMemory
result.MaxMemory = mem.MaxMemory
result.Streams = limit.Streams
result.StreamsInbound = limit.StreamsInbound
result.StreamsOutbound = limit.StreamsOutbound
result.Conns = limit.Conns
result.ConnsInbound = limit.ConnsInbound
result.ConnsOutbound = limit.ConnsOutbound
result.FD = limit.FD
case false:
result.Dynamic = false
result.Memory = mem.GetMemory(int64(memory.TotalMemory()))
result.Streams = limit.Streams
result.StreamsInbound = limit.StreamsInbound
result.StreamsOutbound = limit.StreamsOutbound
result.Conns = limit.Conns
result.ConnsInbound = limit.ConnsInbound
result.ConnsOutbound = limit.ConnsOutbound
result.FD = limit.FD
Comment on lines +422 to +443
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need this?

}

return result
}

handleReset := func(limit rcmgr.BaseLimit, memory rcmgr.MemoryLimit) error {
limitConfig := getDefaultBasicLimitConfig(limit, memory)
return NetSetLimit(mgr, repo, scope, limitConfig)
}

defaultLimits := rcmgr.DefaultLimits
switch {
case scope == config.ResourceMgrSystemScope:
return handleReset(defaultLimits.SystemBaseLimit, defaultLimits.SystemMemory)
case scope == config.ResourceMgrTransientScope:
return handleReset(defaultLimits.TransientBaseLimit, defaultLimits.TransientMemory)
case strings.HasPrefix(scope, config.ResourceMgrServiceScopePrefix):
return handleReset(defaultLimits.ServiceBaseLimit, defaultLimits.ServiceMemory)
case strings.HasPrefix(scope, config.ResourceMgrProtocolScopePrefix):
return handleReset(defaultLimits.ProtocolBaseLimit, defaultLimits.ProtocolMemory)
case strings.HasPrefix(scope, config.ResourceMgrPeerScopePrefix):
return handleReset(defaultLimits.PeerBaseLimit, defaultLimits.PeerMemory)
default:
return fmt.Errorf("invalid scope %q", scope)
}
}