Skip to content

Commit

Permalink
config: warn if connmgr limits conflict with rcmgr (#2527)
Browse files Browse the repository at this point in the history
Co-authored-by: Sukun <sukunrt@gmail.com>
  • Loading branch information
piersy and sukunrt authored Sep 25, 2023
1 parent f6995b1 commit 7f72151
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 0 deletions.
9 changes: 9 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,15 @@ func (cfg *Config) addTransports(h host.Host) error {
//
// This function consumes the config. Do not reuse it (really!).
func (cfg *Config) NewNode() (host.Host, error) {
// If possible check that the resource manager conn limit is higher than the
// limit set in the conn manager.
if l, ok := cfg.ResourceManager.(connmgr.GetConnLimiter); ok {
err := cfg.ConnManager.CheckLimit(l)
if err != nil {
log.Warn(fmt.Sprintf("rcmgr limit conflicts with connmgr limit: %v", err))
}
}

eventBus := eventbus.NewBus(eventbus.WithMetricsTracer(eventbus.NewMetricsTracer(eventbus.WithRegisterer(cfg.PrometheusRegisterer))))
swrm, err := cfg.makeSwarm(eventBus, !cfg.DisableMetrics)
if err != nil {
Expand Down
10 changes: 10 additions & 0 deletions core/connmgr/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ type ConnManager interface {
// then it will return true if the peer is protected for any tag
IsProtected(id peer.ID, tag string) (protected bool)

// CheckLimit will return an error if the connection manager's internal
// connection limit exceeds the provided system limit.
CheckLimit(l GetConnLimiter) error

// Close closes the connection manager and stops background processes.
Close() error
}
Expand All @@ -89,3 +93,9 @@ type TagInfo struct {
// Conns maps connection ids (such as remote multiaddr) to their creation time.
Conns map[string]time.Time
}

// GetConnLimiter provides access to a component's total connection limit.
type GetConnLimiter interface {
// GetConnLimit returns the total connection limit of the implementing component.
GetConnLimit() int
}
1 change: 1 addition & 0 deletions core/connmgr/null.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ func (NullConnMgr) Notifee() network.Notifiee { return network.Gl
func (NullConnMgr) Protect(peer.ID, string) {}
func (NullConnMgr) Unprotect(peer.ID, string) bool { return false }
func (NullConnMgr) IsProtected(peer.ID, string) bool { return false }
func (NullConnMgr) CheckLimit(l GetConnLimiter) error { return nil }
func (NullConnMgr) Close() error { return nil }
4 changes: 4 additions & 0 deletions p2p/host/resource-manager/extapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,3 +145,7 @@ func (r *resourceManager) Stat() (result ResourceManagerStat) {

return result
}

func (r *resourceManager) GetConnLimit() int {
return r.limits.GetConnLimits().GetConnTotalLimit()
}
12 changes: 12 additions & 0 deletions p2p/net/connmgr/connmgr.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package connmgr

import (
"context"
"fmt"
"sort"
"sync"
"sync/atomic"
Expand Down Expand Up @@ -239,6 +240,17 @@ func (cm *BasicConnMgr) IsProtected(id peer.ID, tag string) (protected bool) {
return protected
}

func (cm *BasicConnMgr) CheckLimit(systemLimit connmgr.GetConnLimiter) error {
if cm.cfg.highWater > systemLimit.GetConnLimit() {
return fmt.Errorf(
"conn manager high watermark limit: %d, exceeds the system connection limit of: %d",
cm.cfg.highWater,
systemLimit.GetConnLimit(),
)
}
return nil
}

// peerInfo stores metadata for a given peer.
type peerInfo struct {
id peer.ID
Expand Down
21 changes: 21 additions & 0 deletions p2p/net/connmgr/connmgr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -966,3 +966,24 @@ func TestSafeConcurrency(t *testing.T) {
wg.Wait()
})
}

func TestCheckLimit(t *testing.T) {
low, hi := 1, 2
cm, err := NewConnManager(low, hi)
require.NoError(t, err)

err = cm.CheckLimit(testLimitGetter{hi + 1})
require.NoError(t, err)
err = cm.CheckLimit(testLimitGetter{hi})
require.NoError(t, err)
err = cm.CheckLimit(testLimitGetter{hi - 1})
require.Error(t, err)
}

type testLimitGetter struct {
limit int
}

func (g testLimitGetter) GetConnLimit() int {
return g.limit
}

0 comments on commit 7f72151

Please sign in to comment.