From 9923baa634b5a5ea0394adff6c60d7b3b08f3357 Mon Sep 17 00:00:00 2001 From: wanghongbo Date: Fri, 29 Nov 2024 17:14:34 +0800 Subject: [PATCH 1/9] bugfix: The SDK switches back to the service center recovering from the crash as soon as the server starts, even though the service center has not synced data from the peer yet, which results in an interruption of service discovery. add ut --- datasource/etcd/ops.go | 3 - go.sum | 2 +- pkg/rest/first_launch.go | 70 ++++++++++++++++++++++ pkg/rest/first_launch_test.go | 30 ++++++++++ pkg/rpc/client.go | 5 ++ server/resource/disco/instance_resource.go | 11 +++- server/server.go | 8 ++- server/service/disco/instance.go | 5 +- 8 files changed, 125 insertions(+), 9 deletions(-) create mode 100644 pkg/rest/first_launch.go create mode 100644 pkg/rest/first_launch_test.go diff --git a/datasource/etcd/ops.go b/datasource/etcd/ops.go index 2bbdd5f84..6f48775a7 100644 --- a/datasource/etcd/ops.go +++ b/datasource/etcd/ops.go @@ -98,9 +98,6 @@ func (ds *MetadataManager) CountEnvironment(ctx context.Context, request *ev.Get if err != nil { return nil, err } - if err != nil { - return nil, err - } return &ev.GetEnvironmentCountResponse{ Count: all - preEnvNum, }, nil diff --git a/go.sum b/go.sum index ff31b5d2b..01243bb31 100644 --- a/go.sum +++ b/go.sum @@ -99,7 +99,7 @@ github.com/armon/go-metrics v0.3.10 h1:FR+drcQStOe+32sYyJYyZ7FIdgoGGBnwLl+flodp8 github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= -github.com/armon/go-radix v1.0.0/go.mod h1:TsTFsXBVHVK4HQ+UrFSsQEhBXZGCDqoY+cr+sUq5ZmA= +github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/aws/aws-sdk-go v1.34.28 h1:sscPpn/Ns3i0F4HPEWAVcwdIRaZZCuL7llJ2/60yPIk= diff --git a/pkg/rest/first_launch.go b/pkg/rest/first_launch.go new file mode 100644 index 000000000..647c544dc --- /dev/null +++ b/pkg/rest/first_launch.go @@ -0,0 +1,70 @@ +package rest + +import ( + "errors" + "io/fs" + "os" + "path/filepath" + "time" + + "github.com/apache/servicecomb-service-center/pkg/util" + "github.com/apache/servicecomb-service-center/server/config" + + "github.com/apache/servicecomb-service-center/pkg/log" +) + +/** +for restart service center, set a 2-minute time window to return http status 304 on discovery apis, +indicating that sdk not need to clear cache +*/ + +var ( + isWithinProtection bool + startupTimestamp int64 + firstLaunchFlagPath string + enableInstanceNullProtect bool + restartProtectInterval time.Duration + RestartProtectHttpCode int +) + +func Init() { + enableInstanceNullProtect = config.GetBool("instance_null_protect.enable", true) + restartProtectInterval = time.Duration(config.GetInt("instance_null_protect.restart_protect_interval", 120)) + RestartProtectHttpCode = config.GetInt("instance_null_protect.http_status", 304) + firstLaunchFlagPath = filepath.Join(util.GetAppRoot(), "first_launch.flag") + + _, err := os.Stat(firstLaunchFlagPath) + // first launch, need not instance null protection + if errors.Is(err, fs.ErrNotExist) { + file, err := os.Create(firstLaunchFlagPath) + if err != nil { + log.Error(firstLaunchFlagPath, errors.New("failed to create file")) + os.Exit(1) + } + file.Close() + } else if err != nil { + log.Info("failed to stat flag file") + os.Exit(1) + } + // file exist, not first launch, set protection time window of restartProtectInterval + startupTimestamp = time.Now().UnixNano() + isWithinProtection = true +} + +func IsWithinRestartProtection() bool { + if !enableInstanceNullProtect { + return false + } + + if !isWithinProtection { + return false + } + + if time.Now().Add(-restartProtectInterval).UnixNano() > startupTimestamp { + log.Info("restart protection stop") + isWithinProtection = false + return false + } + log.Info("within restart protection") + return true +} diff --git a/pkg/rest/first_launch_test.go b/pkg/rest/first_launch_test.go new file mode 100644 index 000000000..77226c9c2 --- /dev/null +++ b/pkg/rest/first_launch_test.go @@ -0,0 +1,30 @@ +package rest + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func TestIsWithinRestartProtection(t *testing.T) { + restartProtectInterval = 2 * time.Minute + + // protection switch off + enableInstanceNullProtect = false + assert.False(t, IsWithinRestartProtection()) + // within protection + enableInstanceNullProtect = true + isWithinProtection = true + startupTimestamp = time.Now().Add(-1 * time.Minute).UnixNano() + assert.True(t, IsWithinRestartProtection()) + + // protection delay exceed + enableInstanceNullProtect = true + isWithinProtection = true + startupTimestamp = time.Now().Add(-2 * time.Minute).Unix() + assert.False(t, IsWithinRestartProtection()) + + // always false after exceed + assert.False(t, IsWithinRestartProtection()) +} diff --git a/pkg/rpc/client.go b/pkg/rpc/client.go index b67ccee63..3ca428144 100644 --- a/pkg/rpc/client.go +++ b/pkg/rpc/client.go @@ -20,8 +20,10 @@ package rpc import ( "crypto/tls" "errors" + "time" "google.golang.org/grpc" + "google.golang.org/grpc/backoff" "google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/resolver" @@ -50,9 +52,12 @@ func GetPickFirstLbConn(config *Config) (*grpc.ClientConn, error) { } func GetRoundRobinLbConn(config *Config) (*grpc.ClientConn, error) { + connBackoff := backoff.DefaultConfig + connBackoff.MaxDelay = 30 * time.Second return getLbConn(config, func() []grpc.DialOption { return []grpc.DialOption{ grpc.WithDefaultServiceConfig(`{"loadBalancingConfig": [{"round_robin":{}}]}`), + grpc.WithConnectParams(grpc.ConnectParams{Backoff: connBackoff}), } }) } diff --git a/server/resource/disco/instance_resource.go b/server/resource/disco/instance_resource.go index ec336b467..9bcbc69d1 100644 --- a/server/resource/disco/instance_resource.go +++ b/server/resource/disco/instance_resource.go @@ -25,12 +25,13 @@ import ( "github.com/go-chassis/go-chassis/v2/pkg/codec" + pb "github.com/go-chassis/cari/discovery" + "github.com/apache/servicecomb-service-center/datasource" "github.com/apache/servicecomb-service-center/pkg/log" "github.com/apache/servicecomb-service-center/pkg/rest" "github.com/apache/servicecomb-service-center/pkg/util" discosvc "github.com/apache/servicecomb-service-center/server/service/disco" - pb "github.com/go-chassis/cari/discovery" ) type InstanceResource struct { @@ -167,6 +168,10 @@ func (s *InstanceResource) FindInstances(w http.ResponseWriter, r *http.Request) w.WriteHeader(http.StatusNotModified) return } + if len(resp.Instances) == 0 && rest.IsWithinRestartProtection() { + w.WriteHeader(rest.RestartProtectHttpCode) + return + } rest.WriteResponse(w, r, nil, resp) } @@ -266,6 +271,10 @@ func (s *InstanceResource) ListInstance(w http.ResponseWriter, r *http.Request) w.WriteHeader(http.StatusNotModified) return } + if len(resp.Instances) == 0 && rest.IsWithinRestartProtection() { + w.WriteHeader(rest.RestartProtectHttpCode) + return + } rest.WriteResponse(w, r, nil, resp) } diff --git a/server/server.go b/server/server.go index cf9968012..b36e860c2 100644 --- a/server/server.go +++ b/server/server.go @@ -22,13 +22,17 @@ import ( "crypto/tls" "os" + "github.com/gofiber/fiber/v2" + + "github.com/apache/servicecomb-service-center/pkg/rest" "github.com/apache/servicecomb-service-center/server/middleware" "github.com/apache/servicecomb-service-center/server/resource/disco" - "github.com/gofiber/fiber/v2" "github.com/go-chassis/go-chassis/v2" chassisServer "github.com/go-chassis/go-chassis/v2/core/server" + "github.com/go-chassis/foundation/gopool" + "github.com/apache/servicecomb-service-center/datasource" nf "github.com/apache/servicecomb-service-center/pkg/event" "github.com/apache/servicecomb-service-center/pkg/log" @@ -41,7 +45,6 @@ import ( "github.com/apache/servicecomb-service-center/server/plugin/security/tlsconf" "github.com/apache/servicecomb-service-center/server/service/grc" "github.com/apache/servicecomb-service-center/server/service/rbac" - "github.com/go-chassis/foundation/gopool" ) var sc ServiceCenterServer @@ -211,6 +214,7 @@ func (s *ServiceCenterServer) startServices() { func (s *ServiceCenterServer) startAPIService() { s.APIServer.SetHostPort(s.Endpoint.Host, s.Endpoint.Port) + rest.Init() s.APIServer.Start() } diff --git a/server/service/disco/instance.go b/server/service/disco/instance.go index 45b8cc4de..b2c71d22e 100644 --- a/server/service/disco/instance.go +++ b/server/service/disco/instance.go @@ -25,6 +25,9 @@ import ( "sync" "time" + pb "github.com/go-chassis/cari/discovery" + "github.com/go-chassis/cari/pkg/errsvc" + "github.com/apache/servicecomb-service-center/datasource" "github.com/apache/servicecomb-service-center/pkg/log" "github.com/apache/servicecomb-service-center/pkg/util" @@ -33,8 +36,6 @@ import ( "github.com/apache/servicecomb-service-center/server/health" quotasvc "github.com/apache/servicecomb-service-center/server/service/quota" "github.com/apache/servicecomb-service-center/server/service/validator" - pb "github.com/go-chassis/cari/discovery" - "github.com/go-chassis/cari/pkg/errsvc" ) const ( From a4831e1072bbd658439803dbdf84a2262b8df16b Mon Sep 17 00:00:00 2001 From: Wanghb1 <101036628+Wanghb1@users.noreply.github.com> Date: Mon, 2 Dec 2024 10:12:54 +0800 Subject: [PATCH 2/9] Update first_launch.go --- pkg/rest/first_launch.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/rest/first_launch.go b/pkg/rest/first_launch.go index 647c544dc..519c936f7 100644 --- a/pkg/rest/first_launch.go +++ b/pkg/rest/first_launch.go @@ -29,7 +29,7 @@ var ( func Init() { enableInstanceNullProtect = config.GetBool("instance_null_protect.enable", true) - restartProtectInterval = time.Duration(config.GetInt("instance_null_protect.restart_protect_interval", 120)) + restartProtectInterval = time.Duration(config.GetInt("instance_null_protect.restart_protect_interval", 120)) * time.Second RestartProtectHttpCode = config.GetInt("instance_null_protect.http_status", 304) firstLaunchFlagPath = filepath.Join(util.GetAppRoot(), "first_launch.flag") From 9f08d34ebafb584fe114ad48c627df09cc49270d Mon Sep 17 00:00:00 2001 From: Wanghb1 <101036628+Wanghb1@users.noreply.github.com> Date: Mon, 2 Dec 2024 11:21:14 +0800 Subject: [PATCH 3/9] Update first_launch.go --- pkg/rest/first_launch.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/rest/first_launch.go b/pkg/rest/first_launch.go index 519c936f7..f0a516b05 100644 --- a/pkg/rest/first_launch.go +++ b/pkg/rest/first_launch.go @@ -31,7 +31,7 @@ func Init() { enableInstanceNullProtect = config.GetBool("instance_null_protect.enable", true) restartProtectInterval = time.Duration(config.GetInt("instance_null_protect.restart_protect_interval", 120)) * time.Second RestartProtectHttpCode = config.GetInt("instance_null_protect.http_status", 304) - firstLaunchFlagPath = filepath.Join(util.GetAppRoot(), "first_launch.flag") + firstLaunchFlagPath = filepath.Join(config.GetString("log.file", "", config.WithStandby("logfile")), "first_launch.flag") _, err := os.Stat(firstLaunchFlagPath) // first launch, need not instance null protection From f651b8987b4d5123ddaf55860b177422c601d839 Mon Sep 17 00:00:00 2001 From: Wanghb1 <101036628+Wanghb1@users.noreply.github.com> Date: Mon, 2 Dec 2024 11:28:19 +0800 Subject: [PATCH 4/9] Update first_launch.go --- pkg/rest/first_launch.go | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/rest/first_launch.go b/pkg/rest/first_launch.go index f0a516b05..e295a1c1b 100644 --- a/pkg/rest/first_launch.go +++ b/pkg/rest/first_launch.go @@ -7,7 +7,6 @@ import ( "path/filepath" "time" - "github.com/apache/servicecomb-service-center/pkg/util" "github.com/apache/servicecomb-service-center/server/config" "github.com/apache/servicecomb-service-center/pkg/log" From 18b0dbb5665e756c4da3f2e9025ba2620ca68ad4 Mon Sep 17 00:00:00 2001 From: Wanghb1 <101036628+Wanghb1@users.noreply.github.com> Date: Mon, 2 Dec 2024 14:20:57 +0800 Subject: [PATCH 5/9] Update first_launch.go --- pkg/rest/first_launch.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/rest/first_launch.go b/pkg/rest/first_launch.go index e295a1c1b..0148db34e 100644 --- a/pkg/rest/first_launch.go +++ b/pkg/rest/first_launch.go @@ -42,7 +42,7 @@ func Init() { } file.Close() } else if err != nil { - log.Info("failed to stat flag file") + log.Error(firstLaunchFlagPath, errors.New("failed to stat flag file")) os.Exit(1) } // file exist, not first launch, set protection time window of restartProtectInterval From c1830e3035c619e2c649faa8885c9bc6e07f1d3e Mon Sep 17 00:00:00 2001 From: Wanghb1 <101036628+Wanghb1@users.noreply.github.com> Date: Mon, 2 Dec 2024 14:34:37 +0800 Subject: [PATCH 6/9] Update first_launch.go --- pkg/rest/first_launch.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/rest/first_launch.go b/pkg/rest/first_launch.go index 0148db34e..bb1e9f63f 100644 --- a/pkg/rest/first_launch.go +++ b/pkg/rest/first_launch.go @@ -30,7 +30,8 @@ func Init() { enableInstanceNullProtect = config.GetBool("instance_null_protect.enable", true) restartProtectInterval = time.Duration(config.GetInt("instance_null_protect.restart_protect_interval", 120)) * time.Second RestartProtectHttpCode = config.GetInt("instance_null_protect.http_status", 304) - firstLaunchFlagPath = filepath.Join(config.GetString("log.file", "", config.WithStandby("logfile")), "first_launch.flag") + logDir := filepath.Dir(config.GetString("log.file", "", config.WithStandby("logfile"))) + firstLaunchFlagPath = filepath.Join(logDir, "first_launch.flag") _, err := os.Stat(firstLaunchFlagPath) // first launch, need not instance null protection From 98a0a0e9f7b47fcd7d01c40da4201addd17605fd Mon Sep 17 00:00:00 2001 From: Wanghb1 <101036628+Wanghb1@users.noreply.github.com> Date: Mon, 2 Dec 2024 15:10:15 +0800 Subject: [PATCH 7/9] Update first_launch.go --- pkg/rest/first_launch.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/rest/first_launch.go b/pkg/rest/first_launch.go index bb1e9f63f..d4f922114 100644 --- a/pkg/rest/first_launch.go +++ b/pkg/rest/first_launch.go @@ -49,6 +49,7 @@ func Init() { // file exist, not first launch, set protection time window of restartProtectInterval startupTimestamp = time.Now().UnixNano() isWithinProtection = true + log.Info("set restart instance null protection") } func IsWithinRestartProtection() bool { From ceeb7e295f402d0c70cf79daea9620c3ae7a6565 Mon Sep 17 00:00:00 2001 From: wanghongbo Date: Mon, 2 Dec 2024 16:49:34 +0800 Subject: [PATCH 8/9] review --- pkg/protect/protect.go | 71 +++++++++++++++++++ .../protect_test.go} | 2 +- pkg/rest/first_launch.go | 71 ------------------- pkg/util/util.go | 16 +++++ pkg/util/util_test.go | 7 ++ server/resource/disco/instance_resource.go | 9 +-- server/server.go | 4 +- 7 files changed, 102 insertions(+), 78 deletions(-) create mode 100644 pkg/protect/protect.go rename pkg/{rest/first_launch_test.go => protect/protect_test.go} (97%) delete mode 100644 pkg/rest/first_launch.go diff --git a/pkg/protect/protect.go b/pkg/protect/protect.go new file mode 100644 index 000000000..fedcf6e77 --- /dev/null +++ b/pkg/protect/protect.go @@ -0,0 +1,71 @@ +package protect + +import ( + "fmt" + "github.com/apache/servicecomb-service-center/pkg/util" + "net/http" + "time" + + "github.com/apache/servicecomb-service-center/server/config" + + "github.com/apache/servicecomb-service-center/pkg/log" +) + +/** +for restart service center, set a restartProtectInterval time window to return RestartProtectHttpCode on discovery apis, +indicating that sdk not need to clear cache +*/ + +var ( + isWithinProtection bool + startupTimestamp int64 + enableInstanceNullProtect bool + restartProtectInterval time.Duration + RestartProtectHttpCode int + validProtectCode = []int{http.StatusNotModified, http.StatusUnprocessableEntity, http.StatusInternalServerError} +) + +const ( + maxInterval = 120 * time.Second + minInterval = 0 * time.Second + defaultRestartProtectInterval = 120 * time.Second +) + +func Init() { + enableInstanceNullProtect = config.GetBool("instance_null_protect.enable", false) + restartProtectInterval = time.Duration(config.GetInt("instance_null_protect.restart_protect_interval", 120)) * time.Second + if restartProtectInterval > maxInterval || restartProtectInterval < minInterval { + log.Warn(fmt.Sprintf("invalid instance_null_protect.restart_protect_interval: %d,"+ + " must between %d-%ds inclusively", restartProtectInterval, minInterval, maxInterval)) + restartProtectInterval = defaultRestartProtectInterval + } + RestartProtectHttpCode = config.GetInt("instance_null_protect.http_status", http.StatusNotModified) + if !util.Contains(validProtectCode, RestartProtectHttpCode) { + log.Warn(fmt.Sprintf("invalid instance_null_protect.http_status: %d, must be %v", RestartProtectHttpCode, validProtectCode)) + RestartProtectHttpCode = http.StatusNotModified + } + + log.Info(fmt.Sprintf("instance_null_protect.enable: %t", enableInstanceNullProtect)) + log.Info(fmt.Sprintf("instance_null_protect.restart_protect_interval: %d", restartProtectInterval)) + log.Info(fmt.Sprintf("instance_null_protect.http_status: %d", RestartProtectHttpCode)) + startupTimestamp = time.Now().UnixNano() + isWithinProtection = true +} + +func IsWithinRestartProtection() bool { + if !enableInstanceNullProtect { + return false + } + + if !isWithinProtection { + return false + } + + if time.Now().Add(-restartProtectInterval).UnixNano() > startupTimestamp { + log.Info("restart protection stop") + isWithinProtection = false + return false + } + log.Info("within restart protection") + return true +} diff --git a/pkg/rest/first_launch_test.go b/pkg/protect/protect_test.go similarity index 97% rename from pkg/rest/first_launch_test.go rename to pkg/protect/protect_test.go index 77226c9c2..c7c2dd50c 100644 --- a/pkg/rest/first_launch_test.go +++ b/pkg/protect/protect_test.go @@ -1,4 +1,4 @@ -package rest +package protect import ( "testing" diff --git a/pkg/rest/first_launch.go b/pkg/rest/first_launch.go deleted file mode 100644 index d4f922114..000000000 --- a/pkg/rest/first_launch.go +++ /dev/null @@ -1,71 +0,0 @@ -package rest - -import ( - "errors" - "io/fs" - "os" - "path/filepath" - "time" - - "github.com/apache/servicecomb-service-center/server/config" - - "github.com/apache/servicecomb-service-center/pkg/log" -) - -/** -for restart service center, set a 2-minute time window to return http status 304 on discovery apis, -indicating that sdk not need to clear cache -*/ - -var ( - isWithinProtection bool - startupTimestamp int64 - firstLaunchFlagPath string - enableInstanceNullProtect bool - restartProtectInterval time.Duration - RestartProtectHttpCode int -) - -func Init() { - enableInstanceNullProtect = config.GetBool("instance_null_protect.enable", true) - restartProtectInterval = time.Duration(config.GetInt("instance_null_protect.restart_protect_interval", 120)) * time.Second - RestartProtectHttpCode = config.GetInt("instance_null_protect.http_status", 304) - logDir := filepath.Dir(config.GetString("log.file", "", config.WithStandby("logfile"))) - firstLaunchFlagPath = filepath.Join(logDir, "first_launch.flag") - - _, err := os.Stat(firstLaunchFlagPath) - // first launch, need not instance null protection - if errors.Is(err, fs.ErrNotExist) { - file, err := os.Create(firstLaunchFlagPath) - if err != nil { - log.Error(firstLaunchFlagPath, errors.New("failed to create file")) - os.Exit(1) - } - file.Close() - } else if err != nil { - log.Error(firstLaunchFlagPath, errors.New("failed to stat flag file")) - os.Exit(1) - } - // file exist, not first launch, set protection time window of restartProtectInterval - startupTimestamp = time.Now().UnixNano() - isWithinProtection = true - log.Info("set restart instance null protection") -} - -func IsWithinRestartProtection() bool { - if !enableInstanceNullProtect { - return false - } - - if !isWithinProtection { - return false - } - - if time.Now().Add(-restartProtectInterval).UnixNano() > startupTimestamp { - log.Info("restart protection stop") - isWithinProtection = false - return false - } - log.Info("within restart protection") - return true -} diff --git a/pkg/util/util.go b/pkg/util/util.go index 525518697..21dcbcfe6 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -194,3 +194,19 @@ func GeneratePassword() (string, error) { } return pass, nil } + +// Contains reports whether v is present in s. +func Contains[S ~[]E, E comparable](s S, v E) bool { + return Index(s, v) >= 0 +} + +// Index returns the index of the first occurrence of v in s, +// or -1 if not present. +func Index[S ~[]E, E comparable](s S, v E) int { + for i := range s { + if v == s[i] { + return i + } + } + return -1 +} diff --git a/pkg/util/util_test.go b/pkg/util/util_test.go index 4950ea5b3..51220a0fb 100644 --- a/pkg/util/util_test.go +++ b/pkg/util/util_test.go @@ -17,6 +17,7 @@ package util import ( + "net/http" "os" "testing" @@ -184,3 +185,9 @@ func TestGeneratePassword(t *testing.T) { assert.NoError(t, err) assert.Equal(t, 8, len(password), password) } + +func TestContains(t *testing.T) { + slc := []int{http.StatusNotModified, http.StatusUnprocessableEntity, http.StatusInternalServerError} + assert.True(t, Contains(slc, 304)) + assert.False(t, Contains(slc, 100)) +} diff --git a/server/resource/disco/instance_resource.go b/server/resource/disco/instance_resource.go index 9bcbc69d1..df5fb1458 100644 --- a/server/resource/disco/instance_resource.go +++ b/server/resource/disco/instance_resource.go @@ -19,6 +19,7 @@ package disco import ( "fmt" + "github.com/apache/servicecomb-service-center/pkg/protect" "io" "net/http" "strings" @@ -168,8 +169,8 @@ func (s *InstanceResource) FindInstances(w http.ResponseWriter, r *http.Request) w.WriteHeader(http.StatusNotModified) return } - if len(resp.Instances) == 0 && rest.IsWithinRestartProtection() { - w.WriteHeader(rest.RestartProtectHttpCode) + if len(resp.Instances) == 0 && protect.IsWithinRestartProtection() { + w.WriteHeader(protect.RestartProtectHttpCode) return } rest.WriteResponse(w, r, nil, resp) @@ -271,8 +272,8 @@ func (s *InstanceResource) ListInstance(w http.ResponseWriter, r *http.Request) w.WriteHeader(http.StatusNotModified) return } - if len(resp.Instances) == 0 && rest.IsWithinRestartProtection() { - w.WriteHeader(rest.RestartProtectHttpCode) + if len(resp.Instances) == 0 && protect.IsWithinRestartProtection() { + w.WriteHeader(protect.RestartProtectHttpCode) return } rest.WriteResponse(w, r, nil, resp) diff --git a/server/server.go b/server/server.go index b36e860c2..b05be2f3f 100644 --- a/server/server.go +++ b/server/server.go @@ -20,11 +20,11 @@ package server import ( "context" "crypto/tls" + "github.com/apache/servicecomb-service-center/pkg/protect" "os" "github.com/gofiber/fiber/v2" - "github.com/apache/servicecomb-service-center/pkg/rest" "github.com/apache/servicecomb-service-center/server/middleware" "github.com/apache/servicecomb-service-center/server/resource/disco" @@ -214,7 +214,7 @@ func (s *ServiceCenterServer) startServices() { func (s *ServiceCenterServer) startAPIService() { s.APIServer.SetHostPort(s.Endpoint.Host, s.Endpoint.Port) - rest.Init() + protect.Init() s.APIServer.Start() } From 2905de96d3cfe9220de0d890cc32b4cda67227b6 Mon Sep 17 00:00:00 2001 From: wanghongbo Date: Mon, 2 Dec 2024 17:39:48 +0800 Subject: [PATCH 9/9] review --- pkg/protect/protect.go | 8 +++++--- pkg/util/util.go | 16 ---------------- pkg/util/util_test.go | 7 ------- 3 files changed, 5 insertions(+), 26 deletions(-) diff --git a/pkg/protect/protect.go b/pkg/protect/protect.go index fedcf6e77..59cf5d9f0 100644 --- a/pkg/protect/protect.go +++ b/pkg/protect/protect.go @@ -2,7 +2,6 @@ package protect import ( "fmt" - "github.com/apache/servicecomb-service-center/pkg/util" "net/http" "time" @@ -22,7 +21,7 @@ var ( enableInstanceNullProtect bool restartProtectInterval time.Duration RestartProtectHttpCode int - validProtectCode = []int{http.StatusNotModified, http.StatusUnprocessableEntity, http.StatusInternalServerError} + validProtectCode = map[int]struct{}{http.StatusNotModified: {}, http.StatusUnprocessableEntity: {}, http.StatusInternalServerError: {}} ) const ( @@ -33,6 +32,9 @@ const ( func Init() { enableInstanceNullProtect = config.GetBool("instance_null_protect.enable", false) + if !enableInstanceNullProtect { + return + } restartProtectInterval = time.Duration(config.GetInt("instance_null_protect.restart_protect_interval", 120)) * time.Second if restartProtectInterval > maxInterval || restartProtectInterval < minInterval { log.Warn(fmt.Sprintf("invalid instance_null_protect.restart_protect_interval: %d,"+ @@ -40,7 +42,7 @@ func Init() { restartProtectInterval = defaultRestartProtectInterval } RestartProtectHttpCode = config.GetInt("instance_null_protect.http_status", http.StatusNotModified) - if !util.Contains(validProtectCode, RestartProtectHttpCode) { + if _, ok := validProtectCode[RestartProtectHttpCode]; !ok { log.Warn(fmt.Sprintf("invalid instance_null_protect.http_status: %d, must be %v", RestartProtectHttpCode, validProtectCode)) RestartProtectHttpCode = http.StatusNotModified } diff --git a/pkg/util/util.go b/pkg/util/util.go index 21dcbcfe6..525518697 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -194,19 +194,3 @@ func GeneratePassword() (string, error) { } return pass, nil } - -// Contains reports whether v is present in s. -func Contains[S ~[]E, E comparable](s S, v E) bool { - return Index(s, v) >= 0 -} - -// Index returns the index of the first occurrence of v in s, -// or -1 if not present. -func Index[S ~[]E, E comparable](s S, v E) int { - for i := range s { - if v == s[i] { - return i - } - } - return -1 -} diff --git a/pkg/util/util_test.go b/pkg/util/util_test.go index 51220a0fb..4950ea5b3 100644 --- a/pkg/util/util_test.go +++ b/pkg/util/util_test.go @@ -17,7 +17,6 @@ package util import ( - "net/http" "os" "testing" @@ -185,9 +184,3 @@ func TestGeneratePassword(t *testing.T) { assert.NoError(t, err) assert.Equal(t, 8, len(password), password) } - -func TestContains(t *testing.T) { - slc := []int{http.StatusNotModified, http.StatusUnprocessableEntity, http.StatusInternalServerError} - assert.True(t, Contains(slc, 304)) - assert.False(t, Contains(slc, 100)) -}