feat: seed max concurrent (#3482)

Signed-off-by: Jim Ma <majinjing3@gmail.com>
This commit is contained in:
Jim Ma 2024-09-23 10:41:52 +08:00 committed by GitHub
parent b226996977
commit 3e73231130
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 41 additions and 5 deletions

View File

@ -329,6 +329,7 @@ type DownloadOption struct {
ResourceClients ResourceClientsOption `mapstructure:"resourceClients" yaml:"resourceClients"` ResourceClients ResourceClientsOption `mapstructure:"resourceClients" yaml:"resourceClients"`
RecursiveConcurrent RecursiveConcurrent `mapstructure:"recursiveConcurrent" yaml:"recursiveConcurrent"` RecursiveConcurrent RecursiveConcurrent `mapstructure:"recursiveConcurrent" yaml:"recursiveConcurrent"`
SeedConcurrent int64 `mapstructure:"seedConcurrent" yaml:"seedConcurrent"`
CacheRecursiveMetadata time.Duration `mapstructure:"cacheRecursiveMetadata" yaml:"cacheRecursiveMetadata"` CacheRecursiveMetadata time.Duration `mapstructure:"cacheRecursiveMetadata" yaml:"cacheRecursiveMetadata"`
} }

View File

@ -360,7 +360,8 @@ func New(opt *config.DaemonOption, d dfpath.Dfpath) (Daemon, error) {
} }
rpcManager, err := rpcserver.New(host, peerTaskManager, storageManager, peerExchangeRPC, schedulerClient, rpcManager, err := rpcserver.New(host, peerTaskManager, storageManager, peerExchangeRPC, schedulerClient,
opt.Download.RecursiveConcurrent.GoroutineCount, opt.Download.CacheRecursiveMetadata, downloadServerOption, peerServerOption) opt.Download.RecursiveConcurrent.GoroutineCount, opt.Download.SeedConcurrent,
opt.Download.CacheRecursiveMetadata, downloadServerOption, peerServerOption)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -103,7 +103,8 @@ func init() {
} }
func New(peerHost *schedulerv1.PeerHost, peerTaskManager peer.TaskManager, func New(peerHost *schedulerv1.PeerHost, peerTaskManager peer.TaskManager,
storageManager storage.Manager, peerExchanger pex.PeerExchangeRPC, schedulerClient schedulerclient.V1, recursiveConcurrent int, cacheRecursiveMetadata time.Duration, storageManager storage.Manager, peerExchanger pex.PeerExchangeRPC, schedulerClient schedulerclient.V1,
recursiveConcurrent int, seedConcurrent int64, cacheRecursiveMetadata time.Duration,
downloadOpts []grpc.ServerOption, peerOpts []grpc.ServerOption) (Server, error) { downloadOpts []grpc.ServerOption, peerOpts []grpc.ServerOption) (Server, error) {
s := &server{ s := &server{
KeepAlive: util.NewKeepAlive("rpc server"), KeepAlive: util.NewKeepAlive("rpc server"),
@ -121,6 +122,8 @@ func New(peerHost *schedulerv1.PeerHost, peerTaskManager peer.TaskManager,
sd := &seeder{ sd := &seeder{
server: s, server: s,
maxConcurrent: seedConcurrent,
concurrent: atomic.NewInt64(0),
} }
// set not serving by default // set not serving by default

View File

@ -76,7 +76,7 @@ func TestServer_New(t *testing.T) {
mockSchedulerClient := schedulerclientmocks.NewMockV1(ctrl) mockSchedulerClient := schedulerclientmocks.NewMockV1(ctrl)
var mockdownloadOpts []grpc.ServerOption var mockdownloadOpts []grpc.ServerOption
var mockpeerOpts []grpc.ServerOption var mockpeerOpts []grpc.ServerOption
_, err := New(mockpeerHost, mockpeerTaskManager, mockStorageManger, nil, mockSchedulerClient, 16, 0, mockdownloadOpts, mockpeerOpts) _, err := New(mockpeerHost, mockpeerTaskManager, mockStorageManger, nil, mockSchedulerClient, 16, 0, 0, mockdownloadOpts, mockpeerOpts)
tc.expect(t, err) tc.expect(t, err)
}) })
} }

View File

@ -22,6 +22,7 @@ import (
"math" "math"
"time" "time"
"go.uber.org/atomic"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/status" "google.golang.org/grpc/status"
@ -39,6 +40,8 @@ import (
) )
type seeder struct { type seeder struct {
maxConcurrent int64
concurrent *atomic.Int64
server *server server *server
} }
@ -55,6 +58,16 @@ func (s *seeder) ObtainSeeds(seedRequest *cdnsystemv1.SeedRequest, seedsServer c
printAuthInfo(seedsServer.Context()) printAuthInfo(seedsServer.Context())
} }
if s.maxConcurrent > 0 {
if s.concurrent.Inc() > s.maxConcurrent {
s.concurrent.Dec()
logger.Infof("seed peer is busying, return ResourceExhausted")
return status.Errorf(codes.ResourceExhausted, "seed peer is busying, limit is %d", s.maxConcurrent)
}
defer s.concurrent.Dec()
}
metrics.SeedPeerConcurrentDownloadGauge.Inc() metrics.SeedPeerConcurrentDownloadGauge.Inc()
defer metrics.SeedPeerConcurrentDownloadGauge.Dec() defer metrics.SeedPeerConcurrentDownloadGauge.Dec()
metrics.SeedPeerDownloadCount.Add(1) metrics.SeedPeerDownloadCount.Add(1)

View File

@ -28,10 +28,13 @@ import (
testifyassert "github.com/stretchr/testify/assert" testifyassert "github.com/stretchr/testify/assert"
"go.opentelemetry.io/otel" "go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/trace" "go.opentelemetry.io/otel/trace"
"go.uber.org/atomic"
"go.uber.org/mock/gomock" "go.uber.org/mock/gomock"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/health" "google.golang.org/grpc/health"
"google.golang.org/grpc/status"
cdnsystemv1 "d7y.io/api/v2/pkg/apis/cdnsystem/v1" cdnsystemv1 "d7y.io/api/v2/pkg/apis/cdnsystem/v1"
commonv1 "d7y.io/api/v2/pkg/apis/common/v1" commonv1 "d7y.io/api/v2/pkg/apis/common/v1"
@ -396,3 +399,18 @@ func setupSeederServerAndClient(t *testing.T, srv *server, sd *seeder, assert *t
return port, client return port, client
} }
func Test_ObtainSeedsResourceExhausted(t *testing.T) {
sd := &seeder{
maxConcurrent: 10,
concurrent: atomic.NewInt64(10),
}
assert := testifyassert.New(t)
err := sd.ObtainSeeds(nil, nil)
assert.Error(err, "ObtainSeeds should return error")
st, ok := status.FromError(err)
assert.True(ok, "error should be status")
assert.Equal(codes.ResourceExhausted, st.Code())
}