You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by ro...@apache.org on 2022/01/20 02:48:41 UTC
[servicecomb-service-center] branch master updated: Refactor: use dlock instead
This is an automated email from the ASF dual-hosted git repository.
robotljw pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-service-center.git
The following commit(s) were added to refs/heads/master by this push:
new 29addbf Refactor: use dlock instead
new d65ef65 Merge pull request #1234 from little-cui/bug
29addbf is described below
commit 29addbf2a2145f9796e4a1b1c188b20d5a128895
Author: little-cui <su...@qq.com>
AuthorDate: Wed Jan 19 21:28:29 2022 +0800
Refactor: use dlock instead
---
datasource/dlock/dlock.go | 33 ----
datasource/dlock/dlock_test.go | 90 -----------
datasource/dlock/init.go | 56 -------
datasource/dlock/options.go | 23 ---
datasource/etcd/account.go | 12 --
datasource/etcd/dlock.go | 90 -----------
datasource/etcd/engine.go | 21 +--
datasource/etcd/etcd.go | 17 +--
datasource/etcd/event/dependency_event_handler.go | 20 +--
datasource/etcd/mux/mux.go | 45 ------
datasource/etcd/role.go | 12 --
datasource/etcd/system.go | 9 --
datasource/manager.go | 3 +-
etc/conf/app.yaml | 2 +-
eventbase/go.mod | 2 +-
eventbase/go.sum | 2 +
go.mod | 2 +-
go.sum | 6 +-
pkg/etcdsync/README.md | 11 --
pkg/etcdsync/mutex.go | 177 ----------------------
pkg/etcdsync/mutex_test.go | 86 -----------
server/bootstrap/bootstrap.go | 3 +
server/config/config.go | 2 +-
server/job/disco/schema.go | 13 +-
server/job/disco/service.go | 13 +-
server/service/dlock/dlock.go | 49 ------
server/service/dlock/dlock_test.go | 95 ------------
server/service/rbac/account_service.go | 12 ++
server/service/rbac/role_service.go | 13 ++
syncer/job/tombstone/tombstone.go | 8 +-
30 files changed, 88 insertions(+), 839 deletions(-)
diff --git a/datasource/dlock/dlock.go b/datasource/dlock/dlock.go
deleted file mode 100644
index a2d0ea4..0000000
--- a/datasource/dlock/dlock.go
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// Package dlock provide distributed lock function
-package dlock
-
-import (
- "errors"
-)
-
-var ErrDLockNotExists = errors.New("DLock do not exist")
-
-type DLock interface {
- Lock(key string, ttl int64) error
- TryLock(key string, ttl int64) error
- Renew(key string) error
- IsHoldLock(key string) bool
- Unlock(key string) error
-}
diff --git a/datasource/dlock/dlock_test.go b/datasource/dlock/dlock_test.go
deleted file mode 100644
index 640020d..0000000
--- a/datasource/dlock/dlock_test.go
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package dlock_test
-
-import (
- "testing"
- "time"
-
- "github.com/stretchr/testify/assert"
-
- "github.com/apache/servicecomb-service-center/datasource/dlock"
- _ "github.com/apache/servicecomb-service-center/test"
-)
-
-func TestDLock(t *testing.T) {
- t.Run("test lock", func(t *testing.T) {
- t.Run("lock the global key for 5s should pass", func(t *testing.T) {
- err := dlock.Instance().Lock("global", 5)
- assert.Nil(t, err)
- isHold := dlock.Instance().IsHoldLock("global")
- assert.Equal(t, true, isHold)
- })
- t.Run("two locks fight for the same lock 5s, one lock should pass, another lock should fail", func(t *testing.T) {
- err := dlock.Instance().Lock("same-lock", 5)
- assert.Nil(t, err)
- isHold := dlock.Instance().IsHoldLock("same-lock")
- assert.Equal(t, true, isHold)
- err = dlock.Instance().TryLock("same-lock", 5)
- assert.NotNil(t, err)
- })
- })
- t.Run("test try lock", func(t *testing.T) {
- t.Run("try lock the try key for 5s should pass", func(t *testing.T) {
- err := dlock.Instance().TryLock("try-lock", 5)
- assert.Nil(t, err)
- isHold := dlock.Instance().IsHoldLock("try-lock")
- assert.Equal(t, true, isHold)
- err = dlock.Instance().TryLock("try-lock", 5)
- assert.NotNil(t, err)
- })
- })
- t.Run("test renew", func(t *testing.T) {
- t.Run("renew the renew key for 5s should pass", func(t *testing.T) {
- err := dlock.Instance().Lock("renew", 5)
- assert.Nil(t, err)
- isHold := dlock.Instance().IsHoldLock("renew")
- assert.Equal(t, true, isHold)
- time.Sleep(3 * time.Second)
- err = dlock.Instance().Renew("renew")
- time.Sleep(2 * time.Second)
- err = dlock.Instance().TryLock("renew", 5)
- assert.NotNil(t, err)
- })
- })
- t.Run("test isHoldLock", func(t *testing.T) {
- t.Run("already owns the lock should pass", func(t *testing.T) {
- err := dlock.Instance().Lock("hold-lock", 5)
- assert.Nil(t, err)
- isHold := dlock.Instance().IsHoldLock("hold-lock")
- assert.Equal(t, true, isHold)
- })
- t.Run("key does not exist should fail", func(t *testing.T) {
- isHold := dlock.Instance().IsHoldLock("not-exist")
- assert.Equal(t, false, isHold)
- })
- })
- t.Run("test unlock", func(t *testing.T) {
- t.Run("unlock the unlock key should pass", func(t *testing.T) {
- err := dlock.Instance().Lock("unlock", 5)
- assert.Nil(t, err)
- err = dlock.Instance().Unlock("unlock")
- assert.Nil(t, err)
- })
- })
-}
diff --git a/datasource/dlock/init.go b/datasource/dlock/init.go
deleted file mode 100644
index 179b255..0000000
--- a/datasource/dlock/init.go
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package dlock
-
-import (
- "fmt"
-
- "github.com/apache/servicecomb-service-center/pkg/log"
-)
-
-type initFunc func(opts Options) (DLock, error)
-
-var (
- plugins = make(map[string]initFunc)
- instance DLock
-)
-
-func Install(pluginImplName string, f initFunc) {
- plugins[pluginImplName] = f
-}
-
-func Init(opts Options) error {
- if opts.Kind == "" {
- return nil
- }
- engineFunc, ok := plugins[opts.Kind]
- if !ok {
- return fmt.Errorf("plugin implement not supported [%s]", opts.Kind)
- }
- var err error
- instance, err = engineFunc(opts)
- if err != nil {
- return err
- }
- log.Info(fmt.Sprintf("dlock plugin [%s] enabled", opts.Kind))
- return nil
-}
-
-func Instance() DLock {
- return instance
-}
diff --git a/datasource/dlock/options.go b/datasource/dlock/options.go
deleted file mode 100644
index 1dfe186..0000000
--- a/datasource/dlock/options.go
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package dlock
-
-// Options contains configuration for plugins
-type Options struct {
- Kind string
-}
diff --git a/datasource/etcd/account.go b/datasource/etcd/account.go
index b6dce6e..82271f2 100644
--- a/datasource/etcd/account.go
+++ b/datasource/etcd/account.go
@@ -18,7 +18,6 @@ package etcd
import (
"context"
"encoding/json"
- "fmt"
"strconv"
"time"
@@ -30,7 +29,6 @@ import (
"github.com/apache/servicecomb-service-center/datasource/etcd/path"
esync "github.com/apache/servicecomb-service-center/datasource/etcd/sync"
"github.com/apache/servicecomb-service-center/datasource/rbac"
- "github.com/apache/servicecomb-service-center/pkg/etcdsync"
"github.com/apache/servicecomb-service-center/pkg/log"
"github.com/apache/servicecomb-service-center/pkg/privacy"
"github.com/apache/servicecomb-service-center/pkg/util"
@@ -50,16 +48,6 @@ type RbacDAO struct {
}
func (ds *RbacDAO) CreateAccount(ctx context.Context, a *crbac.Account) error {
- lock, err := etcdsync.Lock("/account-creating/"+a.Name, -1, false)
- if err != nil {
- return fmt.Errorf("account %s is creating", a.Name)
- }
- defer func() {
- err := lock.Unlock()
- if err != nil {
- log.Error("can not release account lock", err)
- }
- }()
exist, err := ds.AccountExist(ctx, a.Name)
if err != nil {
log.Error("can not save account info", err)
diff --git a/datasource/etcd/dlock.go b/datasource/etcd/dlock.go
deleted file mode 100644
index 3182be7..0000000
--- a/datasource/etcd/dlock.go
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package etcd
-
-import (
- "fmt"
- "sync"
-
- "github.com/apache/servicecomb-service-center/datasource/dlock"
- "github.com/apache/servicecomb-service-center/pkg/log"
- "github.com/little-cui/etcdadpt"
-)
-
-func init() {
- dlock.Install("etcd", NewDLock)
- dlock.Install("embeded_etcd", NewDLock)
- dlock.Install("embedded_etcd", NewDLock)
-}
-
-func NewDLock(opts dlock.Options) (dlock.DLock, error) {
- return &DB{lockMap: sync.Map{}}, nil
-}
-
-type DB struct {
- lockMap sync.Map
-}
-
-func (d *DB) Lock(key string, ttl int64) error {
- lock, err := etcdadpt.Lock(key, ttl)
- if err == nil {
- d.lockMap.Store(key, lock)
- }
- return err
-}
-
-func (d *DB) TryLock(key string, ttl int64) error {
- lock, err := etcdadpt.TryLock(key, ttl)
- if err == nil {
- d.lockMap.Store(key, lock)
- }
- return err
-}
-
-func (d *DB) Renew(key string) error {
- if lock, ok := d.lockMap.Load(key); ok {
- err := lock.(*etcdadpt.DLock).Refresh()
- if err != nil {
- log.Error(fmt.Sprintf("fail to renew key %s", key), err)
- d.lockMap.Delete(key)
- }
- return err
- }
- return dlock.ErrDLockNotExists
-}
-
-func (d *DB) IsHoldLock(key string) bool {
- if lock, ok := d.lockMap.Load(key); ok {
- if lock != nil {
- return true
- }
- }
- return false
-}
-
-func (d *DB) Unlock(key string) error {
- if lock, ok := d.lockMap.Load(key); ok {
- err := lock.(*etcdadpt.DLock).Unlock()
- if err != nil {
- log.Error(fmt.Sprintf("fail to unlock %s", key), err)
- }
- d.lockMap.Delete(key)
- return err
- }
- return dlock.ErrDLockNotExists
-}
diff --git a/datasource/etcd/engine.go b/datasource/etcd/engine.go
index c9345bb..a0d03da 100644
--- a/datasource/etcd/engine.go
+++ b/datasource/etcd/engine.go
@@ -22,14 +22,16 @@ import (
"encoding/json"
"os"
- "github.com/apache/servicecomb-service-center/datasource/etcd/mux"
"github.com/apache/servicecomb-service-center/datasource/etcd/path"
"github.com/apache/servicecomb-service-center/pkg/log"
"github.com/apache/servicecomb-service-center/server/config"
"github.com/apache/servicecomb-service-center/version"
+ "github.com/go-chassis/cari/dlock"
"github.com/little-cui/etcdadpt"
)
+const versionLockKey = "/version-upgrade"
+
type SCManager struct {
}
@@ -44,23 +46,22 @@ func (sm *SCManager) UpgradeServerVersion(ctx context.Context) error {
return etcdadpt.PutBytes(ctx, path.GetServerInfoKey(), bytes)
}
func (sm *SCManager) UpgradeVersion(ctx context.Context) error {
- lock, err := mux.Lock(mux.GlobalLock)
-
- if err != nil {
+ if err := dlock.Lock(versionLockKey, -1); err != nil {
log.Error("wait for server ready failed", err)
return err
}
+ defer func() {
+ if err := dlock.Unlock(versionLockKey); err != nil {
+ log.Error("unlock failed", err)
+ }
+ }()
+
if needUpgrade(ctx) {
config.Server.Version = version.Ver().Version
-
if err := sm.UpgradeServerVersion(ctx); err != nil {
log.Error("upgrade server version failed", err)
os.Exit(1)
}
}
- err = lock.Unlock()
- if err != nil {
- log.Error("", err)
- }
- return err
+ return nil
}
diff --git a/datasource/etcd/etcd.go b/datasource/etcd/etcd.go
index 19ab461..55884bf 100644
--- a/datasource/etcd/etcd.go
+++ b/datasource/etcd/etcd.go
@@ -24,17 +24,19 @@ import (
"github.com/apache/servicecomb-service-center/datasource"
"github.com/apache/servicecomb-service-center/datasource/etcd/event"
- "github.com/apache/servicecomb-service-center/datasource/etcd/mux"
"github.com/apache/servicecomb-service-center/datasource/etcd/sd"
"github.com/apache/servicecomb-service-center/datasource/etcd/state"
tracer "github.com/apache/servicecomb-service-center/datasource/etcd/tracing"
"github.com/apache/servicecomb-service-center/pkg/log"
"github.com/apache/servicecomb-service-center/server/config"
+ "github.com/go-chassis/cari/dlock"
"github.com/go-chassis/foundation/gopool"
"github.com/little-cui/etcdadpt"
"github.com/little-cui/etcdadpt/middleware/tracing"
)
+const compactLockKey = "/etcd-compact"
+
var clustersIndex = make(map[string]int)
func init() {
@@ -99,7 +101,7 @@ func NewDataSource(opts datasource.Options) (datasource.DataSource, error) {
InstanceTTL: opts.InstanceTTL,
InstanceProperties: opts.InstanceProperties,
}
- inst.sysManager = newSysManager()
+ inst.sysManager = &SysManager{}
inst.depManager = &DepManager{}
inst.scManager = &SCManager{}
inst.metricsManager = &MetricsManager{}
@@ -172,19 +174,16 @@ func (ds *DataSource) autoCompact() {
case <-ctx.Done():
return
case <-time.After(interval):
- lock, err := mux.Try(mux.GlobalLock)
- if err != nil {
+ if err := dlock.TryLock(compactLockKey, -1); err != nil {
log.Error("can not compact backend by this service center instance now", err)
continue
}
-
- err = etcdadpt.Instance().Compact(ctx, delta)
+ err := etcdadpt.Instance().Compact(ctx, delta)
if err != nil {
log.Error("", err)
}
-
- if err := lock.Unlock(); err != nil {
- log.Error("", err)
+ if err := dlock.Unlock(compactLockKey); err != nil {
+ log.Error("unlock failed", err)
}
}
}
diff --git a/datasource/etcd/event/dependency_event_handler.go b/datasource/etcd/event/dependency_event_handler.go
index db0730e..4b3b91d 100644
--- a/datasource/etcd/event/dependency_event_handler.go
+++ b/datasource/etcd/event/dependency_event_handler.go
@@ -24,7 +24,6 @@ import (
"time"
"github.com/apache/servicecomb-service-center/datasource"
- "github.com/apache/servicecomb-service-center/datasource/etcd/mux"
"github.com/apache/servicecomb-service-center/datasource/etcd/path"
"github.com/apache/servicecomb-service-center/datasource/etcd/sd"
"github.com/apache/servicecomb-service-center/datasource/etcd/state/kvstore"
@@ -34,6 +33,7 @@ import (
"github.com/apache/servicecomb-service-center/pkg/util"
"github.com/apache/servicecomb-service-center/server/config"
pb "github.com/go-chassis/cari/discovery"
+ "github.com/go-chassis/cari/dlock"
"github.com/go-chassis/foundation/backoff"
"github.com/go-chassis/foundation/gopool"
"github.com/go-chassis/foundation/stringutil"
@@ -41,7 +41,7 @@ import (
"github.com/little-cui/etcdadpt"
)
-const DepQueueLock mux.ID = "/cse-sr/lock/dep-queue"
+const depQueueLockKey = "/dep-queue"
// just for unit test
var testMux sync.Mutex
@@ -81,22 +81,18 @@ func (h *DependencyEventHandler) backoff(f func(), retries int) int {
func (h *DependencyEventHandler) tryWithBackoff(success func() error, backoff func(), retries int) (int, error) {
defer log.Recover()
- lock, err := mux.Try(DepQueueLock)
- if err != nil {
- log.Error(fmt.Sprintf("try to lock %s failed", DepQueueLock), err)
- return h.backoff(backoff, retries), err
- }
- if lock == nil {
+ if err := dlock.TryLock(depQueueLockKey, -1); err != nil {
+ log.Error(fmt.Sprintf("try to lock %s failed", depQueueLockKey), err)
return 0, nil
}
-
defer func() {
- if err := lock.Unlock(); err != nil {
- log.Error("", err)
+ if err := dlock.Unlock(depQueueLockKey); err != nil {
+ log.Error("unlock failed", err)
}
}()
- err = success()
+
+ err := success()
if err != nil {
log.Error("handle dependency event failed", err)
return h.backoff(backoff, retries), err
diff --git a/datasource/etcd/mux/mux.go b/datasource/etcd/mux/mux.go
deleted file mode 100644
index 7b7e3d8..0000000
--- a/datasource/etcd/mux/mux.go
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package mux
-
-import (
- "reflect"
- "unsafe"
-
- "github.com/apache/servicecomb-service-center/pkg/etcdsync"
-)
-
-type ID string
-
-func (m *ID) String() (s string) {
- pMT := (*reflect.StringHeader)(unsafe.Pointer(m))
- pStr := (*reflect.StringHeader)(unsafe.Pointer(&s))
- pStr.Data = pMT.Data
- pStr.Len = pMT.Len
- return
-}
-
-const GlobalLock ID = "/cse-sr/lock/global"
-
-func Lock(t ID) (*etcdsync.DLock, error) {
- return etcdsync.Lock(t.String(), -1, true)
-}
-
-func Try(t ID) (*etcdsync.DLock, error) {
- return etcdsync.Lock(t.String(), -1, false)
-}
diff --git a/datasource/etcd/role.go b/datasource/etcd/role.go
index dc88832..d58d60c 100644
--- a/datasource/etcd/role.go
+++ b/datasource/etcd/role.go
@@ -20,7 +20,6 @@ package etcd
import (
"context"
"encoding/json"
- "fmt"
"strconv"
"time"
@@ -31,22 +30,11 @@ import (
"github.com/apache/servicecomb-service-center/datasource/etcd/path"
esync "github.com/apache/servicecomb-service-center/datasource/etcd/sync"
"github.com/apache/servicecomb-service-center/datasource/rbac"
- "github.com/apache/servicecomb-service-center/pkg/etcdsync"
"github.com/apache/servicecomb-service-center/pkg/log"
"github.com/apache/servicecomb-service-center/pkg/util"
)
func (rm *RbacDAO) CreateRole(ctx context.Context, r *crbac.Role) error {
- lock, err := etcdsync.Lock("/role-creating/"+r.Name, -1, false)
- if err != nil {
- return fmt.Errorf("role %s is creating", r.Name)
- }
- defer func() {
- err := lock.Unlock()
- if err != nil {
- log.Error("can not release role lock", err)
- }
- }()
key := path.GenerateRBACRoleKey(r.Name)
exist, err := rm.RoleExist(ctx, r.Name)
if err != nil {
diff --git a/datasource/etcd/system.go b/datasource/etcd/system.go
index 33a3b31..8b465e8 100644
--- a/datasource/etcd/system.go
+++ b/datasource/etcd/system.go
@@ -20,26 +20,17 @@ package etcd
import (
"context"
- "github.com/apache/servicecomb-service-center/datasource"
"github.com/apache/servicecomb-service-center/datasource/etcd/sd"
"github.com/apache/servicecomb-service-center/datasource/etcd/state"
"github.com/apache/servicecomb-service-center/datasource/etcd/state/kvstore"
"github.com/apache/servicecomb-service-center/pkg/dump"
- "github.com/apache/servicecomb-service-center/pkg/etcdsync"
"github.com/apache/servicecomb-service-center/pkg/goutil"
"github.com/go-chassis/foundation/gopool"
)
type SysManager struct {
- locks map[string]*etcdsync.DLock
}
-func newSysManager() datasource.SystemManager {
- inst := &SysManager{
- locks: make(map[string]*etcdsync.DLock),
- }
- return inst
-}
func (sm *SysManager) DumpCache(ctx context.Context) *dump.Cache {
var cache dump.Cache
goutil.New(gopool.Configure().WithContext(ctx).Workers(10)).
diff --git a/datasource/manager.go b/datasource/manager.go
index 5d4df71..7ee329e 100644
--- a/datasource/manager.go
+++ b/datasource/manager.go
@@ -20,10 +20,10 @@ package datasource
import (
"fmt"
- "github.com/apache/servicecomb-service-center/datasource/dlock"
"github.com/apache/servicecomb-service-center/datasource/rbac"
"github.com/apache/servicecomb-service-center/datasource/schema"
"github.com/apache/servicecomb-service-center/pkg/log"
+ "github.com/go-chassis/cari/dlock"
)
type dataSourceEngine func(opts Options) (DataSource, error)
@@ -57,7 +57,6 @@ func Init(opts Options) error {
if err != nil {
return err
}
-
err = dlock.Init(dlock.Options{
Kind: opts.Kind,
})
diff --git a/etc/conf/app.yaml b/etc/conf/app.yaml
index 84f6579..d0700ae 100644
--- a/etc/conf/app.yaml
+++ b/etc/conf/app.yaml
@@ -70,7 +70,7 @@ cipher:
ssl:
dir:
# ssl.mode enable ssl or not, set 1 if enable
- mode: 0
+ enable: false
# minimal tls protocol, [TLSv1.0, TLSv1.1, TLSv1.2]
minVersion: TLSv1.2
# ssl.verifyClient enable verify client certification CN
diff --git a/eventbase/go.mod b/eventbase/go.mod
index a9192d0..9f92f8e 100644
--- a/eventbase/go.mod
+++ b/eventbase/go.mod
@@ -1,7 +1,7 @@
module github.com/apache/servicecomb-service-center/eventbase
require (
- github.com/go-chassis/cari v0.5.1-0.20220119105129-dc7bd5491b49
+ github.com/go-chassis/cari v0.5.1-0.20220119150556-8ae374a2649d
github.com/go-chassis/go-archaius v1.5.1
github.com/little-cui/etcdadpt v0.3.2
github.com/stretchr/testify v1.7.0
diff --git a/eventbase/go.sum b/eventbase/go.sum
index 60ccc53..c2f9e33 100644
--- a/eventbase/go.sum
+++ b/eventbase/go.sum
@@ -114,6 +114,8 @@ github.com/go-chassis/cari v0.4.0/go.mod h1:av/19fqwEP4eOC8unL/z67AAbFDwXUCko6SK
github.com/go-chassis/cari v0.5.0/go.mod h1:av/19fqwEP4eOC8unL/z67AAbFDwXUCko6SKa4Avrd8=
github.com/go-chassis/cari v0.5.1-0.20220119105129-dc7bd5491b49 h1:Qy+Q90kqzVrPTRncrkruPDFQOPssoJ86QjnesJMMNLc=
github.com/go-chassis/cari v0.5.1-0.20220119105129-dc7bd5491b49/go.mod h1:tKTzguHTGohMCgkcWNZWtA4TwfcsJrIXpfYxsQtb7uw=
+github.com/go-chassis/cari v0.5.1-0.20220119150556-8ae374a2649d h1:RtBn1T7KmJM1j1+NlBFqaKJWPWPDde9adDQMFHCKMbU=
+github.com/go-chassis/cari v0.5.1-0.20220119150556-8ae374a2649d/go.mod h1:tKTzguHTGohMCgkcWNZWtA4TwfcsJrIXpfYxsQtb7uw=
github.com/go-chassis/foundation v0.2.2-0.20201210043510-9f6d3de40234/go.mod h1:2PjwqpVwYEVaAldl5A58a08viH8p27pNeYaiE3ZxOBA=
github.com/go-chassis/foundation v0.2.2/go.mod h1:2PjwqpVwYEVaAldl5A58a08viH8p27pNeYaiE3ZxOBA=
github.com/go-chassis/foundation v0.3.0/go.mod h1:2PjwqpVwYEVaAldl5A58a08viH8p27pNeYaiE3ZxOBA=
diff --git a/go.mod b/go.mod
index b24c48c..38b99df 100644
--- a/go.mod
+++ b/go.mod
@@ -13,7 +13,7 @@ require (
github.com/deckarep/golang-set v1.7.1
github.com/elithrar/simple-scrypt v1.3.0
github.com/ghodss/yaml v1.0.0
- github.com/go-chassis/cari v0.5.1-0.20220119105129-dc7bd5491b49
+ github.com/go-chassis/cari v0.5.1-0.20220119150556-8ae374a2649d
github.com/go-chassis/foundation v0.4.0
github.com/go-chassis/go-archaius v1.5.1
github.com/go-chassis/go-chassis-extension/protocol/grpc v0.0.0-20210902082902-eb5df922afcd
diff --git a/go.sum b/go.sum
index 7158d8e..293fd19 100644
--- a/go.sum
+++ b/go.sum
@@ -179,8 +179,10 @@ github.com/go-chassis/cari v0.0.0-20201210041921-7b6fbef2df11/go.mod h1:MgtsEI0A
github.com/go-chassis/cari v0.4.0/go.mod h1:av/19fqwEP4eOC8unL/z67AAbFDwXUCko6SKa4Avrd8=
github.com/go-chassis/cari v0.5.0/go.mod h1:av/19fqwEP4eOC8unL/z67AAbFDwXUCko6SKa4Avrd8=
github.com/go-chassis/cari v0.5.1-0.20210823023004-74041d1363c4/go.mod h1:av/19fqwEP4eOC8unL/z67AAbFDwXUCko6SKa4Avrd8=
-github.com/go-chassis/cari v0.5.1-0.20220119105129-dc7bd5491b49 h1:Qy+Q90kqzVrPTRncrkruPDFQOPssoJ86QjnesJMMNLc=
-github.com/go-chassis/cari v0.5.1-0.20220119105129-dc7bd5491b49/go.mod h1:tKTzguHTGohMCgkcWNZWtA4TwfcsJrIXpfYxsQtb7uw=
+github.com/go-chassis/cari v0.5.1-0.20220117143645-570968c7043d h1:9G1yjs6+8wxtZ+Qy4sj6bchEysEnmBqdhGaDALUnfMQ=
+github.com/go-chassis/cari v0.5.1-0.20220117143645-570968c7043d/go.mod h1:tKTzguHTGohMCgkcWNZWtA4TwfcsJrIXpfYxsQtb7uw=
+github.com/go-chassis/cari v0.5.1-0.20220119150556-8ae374a2649d h1:RtBn1T7KmJM1j1+NlBFqaKJWPWPDde9adDQMFHCKMbU=
+github.com/go-chassis/cari v0.5.1-0.20220119150556-8ae374a2649d/go.mod h1:tKTzguHTGohMCgkcWNZWtA4TwfcsJrIXpfYxsQtb7uw=
github.com/go-chassis/foundation v0.2.2-0.20201210043510-9f6d3de40234/go.mod h1:2PjwqpVwYEVaAldl5A58a08viH8p27pNeYaiE3ZxOBA=
github.com/go-chassis/foundation v0.2.2/go.mod h1:2PjwqpVwYEVaAldl5A58a08viH8p27pNeYaiE3ZxOBA=
github.com/go-chassis/foundation v0.3.0/go.mod h1:2PjwqpVwYEVaAldl5A58a08viH8p27pNeYaiE3ZxOBA=
diff --git a/pkg/etcdsync/README.md b/pkg/etcdsync/README.md
deleted file mode 100644
index 6fc9269..0000000
--- a/pkg/etcdsync/README.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# CSE Distributed Etcd lock
-
-## example
-
-```go
-lock, _ := etcdsync.Lock("/test",-1, true)
-defer lock.Unlock()
-//do something
-g += 1
-fmt.Println(g)
-```
\ No newline at end of file
diff --git a/pkg/etcdsync/mutex.go b/pkg/etcdsync/mutex.go
deleted file mode 100644
index 65e28e2..0000000
--- a/pkg/etcdsync/mutex.go
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package etcdsync
-
-import (
- "context"
- "fmt"
- "os"
- "sync"
- "time"
-
- "github.com/apache/servicecomb-service-center/pkg/log"
- "github.com/apache/servicecomb-service-center/pkg/util"
- "github.com/go-chassis/foundation/gopool"
- "github.com/little-cui/etcdadpt"
- "github.com/little-cui/etcdadpt/middleware/metrics"
-)
-
-const (
- DefaultLockTTL = 60
- DefaultRetryTimes = 3
- RootPath = "/cse/etcdsync"
-
- OperationGlobalLock = "GLOBAL_LOCK"
-)
-
-type DLock struct {
- key string
- ctx context.Context
- ttl int64
- mutex *sync.Mutex
- id string
- createAt time.Time
-}
-
-var (
- IsDebug bool
- hostname = util.HostName()
- pid = os.Getpid()
-)
-
-func NewDLock(key string, ttl int64, wait bool) (l *DLock, err error) {
- if len(key) == 0 {
- return nil, nil
- }
- if ttl < 1 {
- ttl = DefaultLockTTL
- }
-
- now := time.Now()
- l = &DLock{
- key: key,
- ctx: context.Background(),
- ttl: ttl,
- id: fmt.Sprintf("%v-%v-%v", hostname, pid, now.Format("20060102-15:04:05.999999999")),
- createAt: now,
- mutex: &sync.Mutex{},
- }
- for try := 1; try <= DefaultRetryTimes; try++ {
- err = l.Lock(wait)
- if err == nil {
- return
- }
-
- if !wait {
- break
- }
- }
- // failed
- log.Error(fmt.Sprintf("Lock key %s failed, id=%s", l.key, l.id), err)
- l = nil
- return
-}
-
-func (m *DLock) ID() string {
- return m.id
-}
-
-func (m *DLock) Lock(wait bool) (err error) {
- if !IsDebug {
- m.mutex.Lock()
- }
-
- log.Info(fmt.Sprintf("Trying to create a lock: key=%s, id=%s", m.key, m.id))
-
- var leaseID int64
- var opts []etcdadpt.OpOption
- if m.ttl > 0 {
- leaseID, err = etcdadpt.Instance().LeaseGrant(m.ctx, m.ttl)
- if err != nil {
- return err
- }
- opts = append(opts, etcdadpt.WithLease(leaseID))
- }
- success, err := etcdadpt.Insert(m.ctx, m.key, m.id, opts...)
- if err == nil && success {
- log.Info(fmt.Sprintf("Create Lock OK, key=%s, id=%s", m.key, m.id))
- return nil
- }
-
- if leaseID > 0 {
- err = etcdadpt.Instance().LeaseRevoke(m.ctx, leaseID)
- if err != nil {
- return err
- }
- }
-
- if m.ttl == 0 || !wait {
- return fmt.Errorf("key %s is locked by id=%s", m.key, m.id)
- }
-
- log.Error(fmt.Sprintf("Key %s is locked, waiting for other node releases it, id=%s", m.key, m.id), err)
-
- ctx, cancel := context.WithTimeout(m.ctx, time.Duration(m.ttl)*time.Second)
- gopool.Go(func(context.Context) {
- defer cancel()
- err := etcdadpt.Instance().Watch(ctx,
- etcdadpt.WithStrKey(m.key),
- etcdadpt.WithWatchCallback(
- func(message string, evt *etcdadpt.Response) error {
- if evt != nil && evt.Action == etcdadpt.ActionDelete {
- // break this for-loop, and try to create the node again.
- return fmt.Errorf("lock released")
- }
- return nil
- }))
- if err != nil {
- log.Warn(fmt.Sprintf("%s, key=%s, id=%s", err.Error(), m.key, m.id))
- }
- })
- select {
- case <-ctx.Done():
- return ctx.Err() // 可以重新尝试获取锁
- case <-m.ctx.Done():
- cancel()
- return m.ctx.Err() // 机制错误,不应该超时的
- }
-}
-
-func (m *DLock) Unlock() (err error) {
- defer func() {
- if !IsDebug {
- m.mutex.Unlock()
- }
-
- metrics.ReportBackendOperationCompleted(OperationGlobalLock, nil, m.createAt)
- }()
-
- for i := 1; i <= DefaultRetryTimes; i++ {
- _, err := etcdadpt.Delete(m.ctx, m.key)
- if err == nil {
- log.Info(fmt.Sprintf("Delete lock OK, key=%s, id=%s", m.key, m.id))
- return nil
- }
- log.Error(fmt.Sprintf("Delete lock failed, key=%s, id=%s", m.key, m.id), err)
- }
- return err
-}
-
-func Lock(key string, ttl int64, wait bool) (*DLock, error) {
- return NewDLock(fmt.Sprintf("%s%s", RootPath, key), ttl, wait)
-}
diff --git a/pkg/etcdsync/mutex_test.go b/pkg/etcdsync/mutex_test.go
deleted file mode 100644
index 589a4a4..0000000
--- a/pkg/etcdsync/mutex_test.go
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package etcdsync_test
-
-// initialize
-import (
- "fmt"
- "testing"
-
- _ "github.com/apache/servicecomb-service-center/server/plugin/tracing/pzipkin"
- _ "github.com/apache/servicecomb-service-center/test"
- _ "github.com/little-cui/etcdadpt/remote"
-
- "github.com/apache/servicecomb-service-center/pkg/etcdsync"
- "github.com/astaxie/beego"
- "github.com/stretchr/testify/assert"
-)
-
-func init() {
- beego.AppConfig.Set("registry_plugin", "etcd")
- //init plugin
- etcdsync.IsDebug = true
-}
-
-func TestLock(t *testing.T) {
- m1, err := etcdsync.Lock("key1", 5, true)
- assert.NoError(t, err)
- assert.NotNil(t, m1)
- t.Log("m1 locked")
-
- ch := make(chan bool)
- go func() {
- m2, err := etcdsync.Lock("key1", 1, false)
-
- assert.Nil(t, m2)
- assert.Error(t, err)
- fmt.Println("m2 try failed")
-
- m2, err = etcdsync.Lock("key1", 1, true)
- assert.Nil(t, m2)
- assert.Error(t, err)
- fmt.Println("m2 timed out")
- ch <- true
- }()
- <-ch
-
- m3, err := etcdsync.Lock("key1", 2, true)
- assert.NoError(t, err)
- assert.NotNil(t, m3)
-
- fmt.Println("m3 locked")
- err = m3.Unlock()
- assert.NoError(t, err)
-
- err = m1.Unlock()
- assert.NoError(t, err)
- fmt.Println("m1 unlocked")
-}
-func BenchmarkLock(b *testing.B) {
- var g = 0
- b.RunParallel(func(pb *testing.PB) {
- for pb.Next() {
- lock, _ := etcdsync.Lock("/test", -1, true)
- //do something
- g += 1
- fmt.Println(g)
- lock.Unlock()
- }
- })
- fmt.Println("Parallel:", b.N)
-}
diff --git a/server/bootstrap/bootstrap.go b/server/bootstrap/bootstrap.go
index 23c292a..0acb817 100644
--- a/server/bootstrap/bootstrap.go
+++ b/server/bootstrap/bootstrap.go
@@ -65,6 +65,9 @@ import (
_ "github.com/apache/servicecomb-service-center/server/job/account"
_ "github.com/apache/servicecomb-service-center/server/job/disco"
+ //dlock
+ _ "github.com/go-chassis/cari/dlock/bootstrap"
+
"github.com/apache/servicecomb-service-center/pkg/log"
"github.com/apache/servicecomb-service-center/server/handler/accesslog"
"github.com/apache/servicecomb-service-center/server/handler/auth"
diff --git a/server/config/config.go b/server/config/config.go
index c1ee4f8..5568dc6 100644
--- a/server/config/config.go
+++ b/server/config/config.go
@@ -154,7 +154,7 @@ func loadServerConfig() ServerConfig {
EnablePProf: GetInt("server.pprof.mode", 0, WithStandby("enable_pprof")) != 0,
- SslEnabled: GetInt("ssl.mode", 1, WithStandby("ssl_mode")) != 0,
+ SslEnabled: GetBool("ssl.enable", true, WithStandby("ssl_mode")),
LogRotateSize: maxLogFileSize,
LogBackupCount: maxLogBackupCount,
diff --git a/server/job/disco/schema.go b/server/job/disco/schema.go
index 2fa2db1..c669a88 100644
--- a/server/job/disco/schema.go
+++ b/server/job/disco/schema.go
@@ -24,7 +24,7 @@ import (
"github.com/apache/servicecomb-service-center/pkg/log"
"github.com/apache/servicecomb-service-center/server/config"
discosvc "github.com/apache/servicecomb-service-center/server/service/disco"
- "github.com/apache/servicecomb-service-center/server/service/dlock"
+ "github.com/go-chassis/cari/dlock"
"github.com/robfig/cron/v3"
)
@@ -49,15 +49,18 @@ func init() {
}
func retireSchema() {
- err := dlock.TryLock(retireSchemaLockKey, retireSchemaLockTTL)
- if err != nil {
+ if err := dlock.TryLock(retireSchemaLockKey, retireSchemaLockTTL); err != nil {
log.Error(fmt.Sprintf("try lock %s failed", retireSchemaLockKey), err)
return
}
- defer dlock.Unlock(retireSchemaLockKey)
+ defer func() {
+ if err := dlock.Unlock(retireSchemaLockKey); err != nil {
+ log.Error("unlock failed", err)
+ }
+ }()
log.Info("start retire schema")
- err = discosvc.RetireSchema(context.Background())
+ err := discosvc.RetireSchema(context.Background())
if err != nil {
log.Error("retire schema failed", err)
}
diff --git a/server/job/disco/service.go b/server/job/disco/service.go
index a4dbef1..1bd64f5 100644
--- a/server/job/disco/service.go
+++ b/server/job/disco/service.go
@@ -25,7 +25,7 @@ import (
"github.com/apache/servicecomb-service-center/pkg/log"
"github.com/apache/servicecomb-service-center/server/config"
discosvc "github.com/apache/servicecomb-service-center/server/service/disco"
- "github.com/apache/servicecomb-service-center/server/service/dlock"
+ "github.com/go-chassis/cari/dlock"
"github.com/robfig/cron/v3"
)
@@ -63,15 +63,18 @@ func startRetireServiceJob() {
}
func retireService(localPlan *datasource.RetirePlan) {
- err := dlock.TryLock(retireServiceLockKey, retireServiceLockTTL)
- if err != nil {
+ if err := dlock.TryLock(retireServiceLockKey, retireServiceLockTTL); err != nil {
log.Error(fmt.Sprintf("try lock %s failed", retireServiceLockKey), err)
return
}
- defer dlock.Unlock(retireServiceLockKey)
+ defer func() {
+ if err := dlock.Unlock(retireServiceLockKey); err != nil {
+ log.Error("unlock failed", err)
+ }
+ }()
log.Info("start retire microservice")
- err = discosvc.RetireService(context.Background(), localPlan)
+ err := discosvc.RetireService(context.Background(), localPlan)
if err != nil {
log.Error("retire microservice failed", err)
}
diff --git a/server/service/dlock/dlock.go b/server/service/dlock/dlock.go
deleted file mode 100644
index d2bd936..0000000
--- a/server/service/dlock/dlock.go
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// Package dlock provide distributed lock function
-package dlock
-
-import (
- "fmt"
-
- "github.com/apache/servicecomb-service-center/datasource/dlock"
- "github.com/apache/servicecomb-service-center/pkg/log"
-)
-
-func Lock(key string, ttl int64) error {
- return dlock.Instance().Lock(key, ttl)
-}
-
-func TryLock(key string, ttl int64) error {
- return dlock.Instance().TryLock(key, ttl)
-}
-
-func Renew(key string) error {
- return dlock.Instance().Renew(key)
-}
-
-func IsHoldLock(key string) bool {
- return dlock.Instance().IsHoldLock(key)
-}
-
-func Unlock(key string) {
- err := dlock.Instance().Unlock(key)
- if err != nil {
- log.Error(fmt.Sprintf("unlock key %s failed", key), err)
- }
-}
diff --git a/server/service/dlock/dlock_test.go b/server/service/dlock/dlock_test.go
deleted file mode 100644
index e981722..0000000
--- a/server/service/dlock/dlock_test.go
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package dlock_test
-
-import (
- "testing"
- "time"
-
- "github.com/stretchr/testify/assert"
-
- "github.com/apache/servicecomb-service-center/server/service/dlock"
- "github.com/apache/servicecomb-service-center/test"
- _ "github.com/apache/servicecomb-service-center/test"
-)
-
-func TestDLock(t *testing.T) {
- if !test.IsETCD() {
- return
- }
- t.Run("test lock", func(t *testing.T) {
- t.Run("lock the global key for 5s should pass", func(t *testing.T) {
- err := dlock.Lock("global", 5)
- assert.Nil(t, err)
- isHold := dlock.IsHoldLock("global")
- assert.Equal(t, true, isHold)
- })
- t.Run("two locks fight for the same lock 5s, one lock should pass, another lock should fail", func(t *testing.T) {
- err := dlock.Lock("same-lock", 5)
- assert.Nil(t, err)
- isHold := dlock.IsHoldLock("same-lock")
- assert.Equal(t, true, isHold)
- err = dlock.TryLock("same-lock", 5)
- assert.NotNil(t, err)
- })
- })
- t.Run("test try lock", func(t *testing.T) {
- t.Run("try lock the try key for 5s should pass", func(t *testing.T) {
- err := dlock.TryLock("try-lock", 5)
- assert.Nil(t, err)
- isHold := dlock.IsHoldLock("try-lock")
- assert.Equal(t, true, isHold)
- err = dlock.TryLock("try-lock", 5)
- assert.NotNil(t, err)
- })
- })
- t.Run("test renew", func(t *testing.T) {
- t.Run("renew the renew key for 5s should pass", func(t *testing.T) {
- err := dlock.Lock("renew", 5)
- assert.Nil(t, err)
- isHold := dlock.IsHoldLock("renew")
- assert.Equal(t, true, isHold)
- time.Sleep(3 * time.Second)
- err = dlock.Renew("renew")
- time.Sleep(2 * time.Second)
- err = dlock.TryLock("renew", 5)
- assert.NotNil(t, err)
- })
- })
- t.Run("test isHoldLock", func(t *testing.T) {
- t.Run("already owns the lock should pass", func(t *testing.T) {
- err := dlock.Lock("hold-lock", 5)
- assert.Nil(t, err)
- isHold := dlock.IsHoldLock("hold-lock")
- assert.Equal(t, true, isHold)
- })
- t.Run("key does not exist should fail", func(t *testing.T) {
- isHold := dlock.IsHoldLock("not-exist")
- assert.Equal(t, false, isHold)
- })
- })
- t.Run("test unlock", func(t *testing.T) {
- t.Run("unlock the unlock key should pass", func(t *testing.T) {
- err := dlock.Lock("unlock", 5)
- assert.Nil(t, err)
- dlock.Unlock("unlock")
- lock := dlock.IsHoldLock("unlock")
- assert.False(t, lock)
- })
- })
-}
diff --git a/server/service/rbac/account_service.go b/server/service/rbac/account_service.go
index 0b4297d..2e9af34 100644
--- a/server/service/rbac/account_service.go
+++ b/server/service/rbac/account_service.go
@@ -28,6 +28,7 @@ import (
quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
"github.com/apache/servicecomb-service-center/server/service/validator"
"github.com/go-chassis/cari/discovery"
+ "github.com/go-chassis/cari/dlock"
rbacmodel "github.com/go-chassis/cari/rbac"
)
@@ -54,6 +55,17 @@ func CreateAccount(ctx context.Context, a *rbacmodel.Account) error {
return rbacmodel.NewError(rbacmodel.ErrAccountHasInvalidRole, err.Error())
}
+ lockKey := "/account-creating/" + a.Name
+ if err := dlock.TryLock(lockKey, -1); err != nil {
+ err = fmt.Errorf("account %s is creating, err: %s", a.Name, err.Error())
+ return discovery.NewError(discovery.ErrInvalidParams, err.Error())
+ }
+ defer func() {
+ if err := dlock.Unlock(lockKey); err != nil {
+ log.Error("unlock failed", err)
+ }
+ }()
+
err = rbac.Instance().CreateAccount(ctx, a)
if err == nil {
log.Info(fmt.Sprintf("create account [%s] success", a.Name))
diff --git a/server/service/rbac/role_service.go b/server/service/rbac/role_service.go
index 98b3236..658370e 100644
--- a/server/service/rbac/role_service.go
+++ b/server/service/rbac/role_service.go
@@ -28,6 +28,7 @@ import (
quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
"github.com/apache/servicecomb-service-center/server/service/validator"
"github.com/go-chassis/cari/discovery"
+ "github.com/go-chassis/cari/dlock"
rbacmodel "github.com/go-chassis/cari/rbac"
)
@@ -41,6 +42,18 @@ func CreateRole(ctx context.Context, r *rbacmodel.Role) error {
if quotaErr != nil {
return rbacmodel.NewError(rbacmodel.ErrRoleNoQuota, quotaErr.Error())
}
+
+ lockKey := "/role-creating/" + r.Name
+ if err := dlock.TryLock(lockKey, -1); err != nil {
+ err = fmt.Errorf("role %s is creating, err: %s", r.Name, err.Error())
+ return discovery.NewError(discovery.ErrInvalidParams, err.Error())
+ }
+ defer func() {
+ if err := dlock.Unlock(lockKey); err != nil {
+ log.Error("unlock failed", err)
+ }
+ }()
+
err = rbac.Instance().CreateRole(ctx, r)
if err == nil {
log.Info(fmt.Sprintf("create role [%s] success", r.Name))
diff --git a/syncer/job/tombstone/tombstone.go b/syncer/job/tombstone/tombstone.go
index 8c6f120..ec36073 100644
--- a/syncer/job/tombstone/tombstone.go
+++ b/syncer/job/tombstone/tombstone.go
@@ -22,8 +22,8 @@ import (
"github.com/apache/servicecomb-service-center/pkg/log"
"github.com/apache/servicecomb-service-center/server/config"
- "github.com/apache/servicecomb-service-center/server/service/dlock"
"github.com/apache/servicecomb-service-center/syncer/service/tombstone"
+ "github.com/go-chassis/cari/dlock"
"github.com/robfig/cron/v3"
)
@@ -57,7 +57,11 @@ func deleteExpireTombStone() {
log.Error(fmt.Sprintf("try lock %s failed", deleteExpireTombstoneLockKey), err)
return
}
- defer dlock.Unlock(deleteExpireTombstoneLockKey)
+ defer func() {
+ if err := dlock.Unlock(deleteExpireTombstoneLockKey); err != nil {
+ log.Error("unlock failed", err)
+ }
+ }()
log.Info("start delete expire tombstone job")
err = tombstone.DeleteExpireTombStone()