Skip to content

Commit

Permalink
fix(registry/polaris): fix concurrent map iteration and map write #3361
Browse files Browse the repository at this point in the history
… (#3386)

* fix(registry/polaris): fix concurrent map iteration and map write #3361

* fix(test): support go 1.20.x

* fix(test): fix test mock concurrent read

* fix: fix Metadata use rmd & remove dup space
  • Loading branch information
Ccheers committed Aug 19, 2024
1 parent 6427904 commit d50609d
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 7 deletions.
30 changes: 23 additions & 7 deletions contrib/polaris/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,15 +115,16 @@ func (r *Registry) Register(_ context.Context, instance *registry.ServiceInstanc
}

// metadata
if instance.Metadata == nil {
instance.Metadata = make(map[string]string)
rmd := mapClone(instance.Metadata)
if rmd == nil {
rmd = make(map[string]string)
}
instance.Metadata["merge"] = id
if _, ok := instance.Metadata["weight"]; !ok {
instance.Metadata["weight"] = strconv.Itoa(r.opt.Weight)
rmd["merge"] = id
if _, ok := rmd["weight"]; !ok {
rmd["weight"] = strconv.Itoa(r.opt.Weight)
}

weight, _ := strconv.Atoi(instance.Metadata["weight"])
weight, _ := strconv.Atoi(rmd["weight"])

_, err = r.provider.RegisterInstance(
&polaris.InstanceRegisterRequest{
Expand All @@ -137,7 +138,7 @@ func (r *Registry) Register(_ context.Context, instance *registry.ServiceInstanc
Weight: &weight,
Priority: &r.opt.Priority,
Version: &instance.Version,
Metadata: instance.Metadata,
Metadata: rmd,
Healthy: &r.opt.Healthy,
Isolate: &r.opt.Isolate,
TTL: &r.opt.TTL,
Expand Down Expand Up @@ -378,3 +379,18 @@ func instancesToServiceInstances(instances map[string][]model.Instance) []*regis
}
return serviceInstances
}

// Clone returns a copy of m. This is a shallow clone:
// the new keys and values are set using ordinary assignment.
func mapClone[M ~map[K]V, K comparable, V any](m M) M {
// Preserve nil in case it matters.
if m == nil {
return nil
}
// Make a shallow copy of the map.
m2 := make(M, len(m))
for k, v := range m {
m2[k] = v
}
return m2
}
15 changes: 15 additions & 0 deletions contrib/polaris/registry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package polaris

import (
"context"
"strconv"
"testing"
"time"

Expand All @@ -28,6 +29,9 @@ func TestRegistry(t *testing.T) {
WithRegistryTTL(1000),
)

mm := map[string]string{
"test1": "test1",
}
ins := &registry.ServiceInstance{
ID: "test-ut",
Name: "test-ut",
Expand All @@ -36,8 +40,19 @@ func TestRegistry(t *testing.T) {
"grpc://127.0.0.1:8080",
"http://127.0.0.1:9090",
},
Metadata: mm,
}

go func() {
for i := 0; true; i++ {
str := "test" + strconv.Itoa(i)
_ = mm[str]
if i > 100 {
i = 0
}
}
}()

err = r.Register(context.Background(), ins)

t.Cleanup(func() {
Expand Down

0 comments on commit d50609d

Please sign in to comment.