@@ -2,7 +2,6 @@ package libp2p
2
2
3
3
import (
4
4
"context"
5
- "errors"
6
5
"fmt"
7
6
"os"
8
7
"path/filepath"
@@ -27,7 +26,6 @@ var NoResourceMgrError = fmt.Errorf("missing ResourceMgr: make sure the daemon i
27
26
28
27
func ResourceManager (cfg config.SwarmConfig ) func (fx.Lifecycle , repo.Repo ) (network.ResourceManager , Libp2pOpts , error ) {
29
28
return func (lc fx.Lifecycle , repo repo.Repo ) (network.ResourceManager , Libp2pOpts , error ) {
30
- var limiter * rcmgr.BasicLimiter
31
29
var manager network.ResourceManager
32
30
var opts Libp2pOpts
33
31
@@ -47,25 +45,18 @@ func ResourceManager(cfg config.SwarmConfig) func(fx.Lifecycle, repo.Repo) (netw
47
45
48
46
repoPath , err := config .PathRoot ()
49
47
if err != nil {
50
- return nil , opts , fmt .Errorf ("error opening IPFS_PATH: %w" , err )
48
+ return nil , opts , fmt .Errorf ("opening IPFS_PATH: %w" , err )
51
49
}
52
50
53
- // Create limiter:
54
- // - parse $IPFS_PATH/limits.json if exists
55
- // - use defaultLimits from rcmgr_defaults.go
56
51
defaultLimits := adjustedDefaultLimits (cfg )
57
- limitFilePath := filepath .Join (repoPath , NetLimitDefaultFilename )
58
- limitFile , err := os .Open (limitFilePath )
59
- switch {
60
- case err == nil :
61
- defer limitFile .Close ()
62
- limiter , err = rcmgr .NewLimiterFromJSON (limitFile , defaultLimits )
63
- if err != nil {
64
- return nil , opts , fmt .Errorf ("error parsing libp2p limit file: %w" , err )
65
- }
66
- case errors .Is (err , os .ErrNotExist ):
67
- limiter = rcmgr .NewStaticLimiter (defaultLimits )
68
- default :
52
+
53
+ var limits rcmgr.BasicLimiterConfig
54
+ if cfg .ResourceMgr .Limits != nil {
55
+ limits = * cfg .ResourceMgr .Limits
56
+ }
57
+
58
+ limiter , err := rcmgr .NewLimiter (limits , defaultLimits )
59
+ if err != nil {
69
60
return nil , opts , err
70
61
}
71
62
@@ -80,9 +71,8 @@ func ResourceManager(cfg config.SwarmConfig) func(fx.Lifecycle, repo.Repo) (netw
80
71
81
72
manager , err = rcmgr .NewResourceManager (limiter , ropts ... )
82
73
if err != nil {
83
- return nil , opts , fmt .Errorf ("error creating libp2p resource manager: %w" , err )
74
+ return nil , opts , fmt .Errorf ("creating libp2p resource manager: %w" , err )
84
75
}
85
-
86
76
} else {
87
77
log .Debug ("libp2p resource manager is disabled" )
88
78
manager = network .NullResourceManager
@@ -196,14 +186,13 @@ func NetStat(mgr network.ResourceManager, scope string) (NetStatOut, error) {
196
186
}
197
187
}
198
188
199
- func NetLimit (mgr network.ResourceManager , scope string ) (config. ResourceMgrScopeConfig , error ) {
200
- var result config. ResourceMgrScopeConfig
189
+ func NetLimit (mgr network.ResourceManager , scope string ) (rcmgr. BasicLimitConfig , error ) {
190
+ var result rcmgr. BasicLimitConfig
201
191
getLimit := func (s network.ResourceScope ) error {
202
192
limiter , ok := s .(rcmgr.ResourceScopeLimiter )
203
193
if ! ok { // NullResourceManager
204
194
return NoResourceMgrError
205
195
}
206
-
207
196
limit := limiter .Limit ()
208
197
switch l := limit .(type ) {
209
198
case * rcmgr.StaticLimit :
@@ -280,7 +269,8 @@ func NetLimit(mgr network.ResourceManager, scope string) (config.ResourceMgrScop
280
269
}
281
270
}
282
271
283
- func NetSetLimit (mgr network.ResourceManager , scope string , limit config.ResourceMgrScopeConfig ) error {
272
+ // NetSetLimit sets new ResourceManager limits for the given scope. The limits take effect immediately, and are also persisted to the repo config.
273
+ func NetSetLimit (mgr network.ResourceManager , repo repo.Repo , scope string , limit rcmgr.BasicLimitConfig ) error {
284
274
setLimit := func (s network.ResourceScope ) error {
285
275
limiter , ok := s .(rcmgr.ResourceScopeLimiter )
286
276
if ! ok { // NullResourceManager
@@ -324,45 +314,87 @@ func NetSetLimit(mgr network.ResourceManager, scope string, limit config.Resourc
324
314
return nil
325
315
}
326
316
317
+ cfg , err := repo .Config ()
318
+ if err != nil {
319
+ return fmt .Errorf ("reading config to set limit: %w" , err )
320
+ }
321
+
322
+ if cfg .Swarm .ResourceMgr .Limits == nil {
323
+ cfg .Swarm .ResourceMgr .Limits = & rcmgr.BasicLimiterConfig {}
324
+ }
325
+ configLimits := cfg .Swarm .ResourceMgr .Limits
326
+
327
+ var setConfigFunc func ()
327
328
switch {
328
329
case scope == config .ResourceMgrSystemScope :
329
- err : = mgr .ViewSystem (func (s network.ResourceScope ) error {
330
+ err = mgr .ViewSystem (func (s network.ResourceScope ) error {
330
331
return setLimit (s )
331
332
})
332
- return err
333
+ setConfigFunc = func () { configLimits . System = & limit }
333
334
334
335
case scope == config .ResourceMgrTransientScope :
335
- err : = mgr .ViewTransient (func (s network.ResourceScope ) error {
336
+ err = mgr .ViewTransient (func (s network.ResourceScope ) error {
336
337
return setLimit (s )
337
338
})
338
- return err
339
+ setConfigFunc = func () { configLimits . Transient = & limit }
339
340
340
341
case strings .HasPrefix (scope , config .ResourceMgrServiceScopePrefix ):
341
- svc := scope [ 4 :]
342
- err : = mgr .ViewService (svc , func (s network.ServiceScope ) error {
342
+ svc := strings . TrimPrefix ( scope , config . ResourceMgrServiceScopePrefix )
343
+ err = mgr .ViewService (svc , func (s network.ServiceScope ) error {
343
344
return setLimit (s )
344
345
})
345
- return err
346
+ setConfigFunc = func () {
347
+ if configLimits .Service == nil {
348
+ configLimits .Service = map [string ]rcmgr.BasicLimitConfig {}
349
+ }
350
+ configLimits .Service [svc ] = limit
351
+ }
346
352
347
353
case strings .HasPrefix (scope , config .ResourceMgrProtocolScopePrefix ):
348
- proto := scope [ 6 :]
349
- err : = mgr .ViewProtocol (protocol .ID (proto ), func (s network.ProtocolScope ) error {
354
+ proto := strings . TrimPrefix ( scope , config . ResourceMgrProtocolScopePrefix )
355
+ err = mgr .ViewProtocol (protocol .ID (proto ), func (s network.ProtocolScope ) error {
350
356
return setLimit (s )
351
357
})
352
- return err
358
+ setConfigFunc = func () {
359
+ if configLimits .Protocol == nil {
360
+ configLimits .Protocol = map [string ]rcmgr.BasicLimitConfig {}
361
+ }
362
+ configLimits .Protocol [proto ] = limit
363
+ }
353
364
354
365
case strings .HasPrefix (scope , config .ResourceMgrPeerScopePrefix ):
355
- p := scope [5 :]
356
- pid , err := peer .Decode (p )
366
+ p := strings .TrimPrefix (scope , config .ResourceMgrPeerScopePrefix )
367
+ var pid peer.ID
368
+ pid , err = peer .Decode (p )
357
369
if err != nil {
358
370
return fmt .Errorf ("invalid peer ID: %q: %w" , p , err )
359
371
}
360
372
err = mgr .ViewPeer (pid , func (s network.PeerScope ) error {
361
373
return setLimit (s )
362
374
})
363
- return err
375
+ setConfigFunc = func () {
376
+ if configLimits .Peer == nil {
377
+ configLimits .Peer = map [string ]rcmgr.BasicLimitConfig {}
378
+ }
379
+ configLimits .Peer [p ] = limit
380
+ }
364
381
365
382
default :
366
383
return fmt .Errorf ("invalid scope %q" , scope )
367
384
}
385
+
386
+ if err != nil {
387
+ return fmt .Errorf ("setting new limits on resource manager: %w" , err )
388
+ }
389
+
390
+ if cfg .Swarm .ResourceMgr .Limits == nil {
391
+ cfg .Swarm .ResourceMgr .Limits = & rcmgr.BasicLimiterConfig {}
392
+ }
393
+ setConfigFunc ()
394
+
395
+ if err := repo .SetConfig (cfg ); err != nil {
396
+ return fmt .Errorf ("writing new limits to repo config: %w" , err )
397
+ }
398
+
399
+ return nil
368
400
}
0 commit comments