Skip to content
This repository has been archived by the owner on Aug 19, 2022. It is now read-only.

Commit

Permalink
add a function to automatically scale limits to system memory / FDs
Browse files Browse the repository at this point in the history
  • Loading branch information
marten-seemann committed Jun 10, 2022
1 parent da2f584 commit 07c38a5
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 2 deletions.
7 changes: 6 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@ go 1.17
require (
github.com/ipfs/go-log/v2 v2.5.0
github.com/libp2p/go-libp2p-core v0.14.0
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58
github.com/stretchr/testify v1.7.0
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c
)

require (
github.com/btcsuite/btcd v0.20.1-beta // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/gogo/protobuf v1.3.1 // indirect
github.com/ipfs/go-cid v0.0.7 // indirect
github.com/libp2p/go-buffer-pool v0.0.2 // indirect
Expand All @@ -23,11 +27,12 @@ require (
github.com/multiformats/go-multibase v0.0.3 // indirect
github.com/multiformats/go-multihash v0.0.14 // indirect
github.com/multiformats/go-varint v0.0.6 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.6.0 // indirect
go.uber.org/zap v1.19.1 // indirect
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 // indirect
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)
5 changes: 5 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlT
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs=
github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM=
Expand Down Expand Up @@ -68,6 +70,8 @@ github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXS
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0=
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
Expand Down Expand Up @@ -125,6 +129,7 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
Expand Down
11 changes: 10 additions & 1 deletion limit_defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (

"github.com/libp2p/go-libp2p-core/peer"
"github.com/libp2p/go-libp2p-core/protocol"

"github.com/pbnjay/memory"
)

type baseLimitConfig struct {
Expand Down Expand Up @@ -176,6 +178,13 @@ func (cfg *ScalingLimitConfig) Scale(memory int64, numFD int) LimitConfig {
return lc
}

func (cfg *ScalingLimitConfig) AutoScale() LimitConfig {
return cfg.Scale(
int64(memory.TotalMemory())/8,
getNumFDs()/2,
)
}

// factor is the number of MBs above the minimum (128 MB)
func scale(base BaseLimit, inc BaseLimitIncrease, factor int, numFD int) BaseLimit {
l := BaseLimit{
Expand All @@ -188,7 +197,7 @@ func scale(base BaseLimit, inc BaseLimitIncrease, factor int, numFD int) BaseLim
Memory: base.Memory + (inc.Memory*int64(factor))>>10,
FD: base.FD,
}
if inc.FDFraction > 0 {
if inc.FDFraction > 0 && numFD > 0 {
l.FD = int(inc.FDFraction * float64(numFD))
}
return l
Expand Down
61 changes: 61 additions & 0 deletions limit_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package rcmgr

import (
"runtime"
"testing"

"github.com/stretchr/testify/require"
)

func TestFileDescriptorCounting(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("can't read file descriptors on Windows")
}
n := getNumFDs()
require.NotZero(t, n)
require.Less(t, n, int(1e6))
}

func TestScaling(t *testing.T) {
base := BaseLimit{
Streams: 100,
StreamsInbound: 200,
StreamsOutbound: 400,
Conns: 10,
ConnsInbound: 20,
ConnsOutbound: 40,
FD: 1,
Memory: 1 << 20,
}

t.Run("no scaling if no increase is defined", func(t *testing.T) {
cfg := ScalingLimitConfig{ServiceBaseLimit: base}
scaled := cfg.Scale(8<<30, 100)
require.Equal(t, base, scaled.DefaultServiceLimit)
})

t.Run("scaling", func(t *testing.T) {
cfg := ScalingLimitConfig{
TransientBaseLimit: base,
TransientLimitIncrease: BaseLimitIncrease{
Streams: 1,
StreamsInbound: 2,
StreamsOutbound: 3,
Conns: 4,
ConnsInbound: 5,
ConnsOutbound: 6,
Memory: 7,
FDFraction: 0.5,
},
}
scaled := cfg.Scale(128<<20+4<<30, 1000)
require.Equal(t, 500, scaled.TransientLimit.FD)
require.Equal(t, base.Streams+4, scaled.TransientLimit.Streams)
require.Equal(t, base.StreamsInbound+4*2, scaled.TransientLimit.StreamsInbound)
require.Equal(t, base.StreamsOutbound+4*3, scaled.TransientLimit.StreamsOutbound)
require.Equal(t, base.Conns+4*4, scaled.TransientLimit.Conns)
require.Equal(t, base.ConnsInbound+4*5, scaled.TransientLimit.ConnsInbound)
require.Equal(t, base.ConnsOutbound+4*6, scaled.TransientLimit.ConnsOutbound)
require.Equal(t, base.Memory+4*7, scaled.TransientLimit.Memory)
})
}
11 changes: 11 additions & 0 deletions sys_not_unix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//go:build !linux && !darwin

package rcmgr

import "runtime"

// TODO: figure out how to get the number of file descriptors on Windows and other systems
func getNumFDs() int {
log.Warnf("cannot determine number of file descriptors on %s", runtime.GOOS)
return 0
}
17 changes: 17 additions & 0 deletions sys_unix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//go:build linux || darwin
// +build linux darwin

package rcmgr

import (
"golang.org/x/sys/unix"
)

func getNumFDs() int {
var l unix.Rlimit
if err := unix.Getrlimit(unix.RLIMIT_NOFILE, &l); err != nil {
log.Errorw("failed to get fd limit", "error", err)
return 0
}
return int(l.Cur)
}

0 comments on commit 07c38a5

Please sign in to comment.