You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@servicecomb.apache.org by GitBox <gi...@apache.org> on 2018/01/23 04:23:55 UTC

[GitHub] asifdxtreme closed pull request #257: SCB-276 Optimize plugins loader

asifdxtreme closed pull request #257: SCB-276 Optimize plugins loader
URL: https://github.com/apache/incubator-servicecomb-service-center/pull/257
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/pkg/plugin/loader.go b/pkg/plugin/loader.go
index 4a173e03..0306ef22 100644
--- a/pkg/plugin/loader.go
+++ b/pkg/plugin/loader.go
@@ -28,26 +28,32 @@ import (
 )
 
 var (
-	pluginManager PluginManager
-	once          sync.Once
+	loader   Loader
+	once     sync.Once
+	regex, _ = regexp.Compile(`([A-Za-z0-9_.-]+)_plugin.so$`)
 )
 
-type PluginManager struct {
+type wrapPlugin struct {
+	p     *plugin.Plugin
+	funcs map[string]plugin.Symbol
+}
+
+type Loader struct {
 	Dir     string
-	Plugins map[string]*plugin.Plugin
+	Plugins map[string]*wrapPlugin
+	mux     sync.RWMutex
 }
 
-func (pm *PluginManager) Init() {
-	pm.Plugins = make(map[string]*plugin.Plugin)
+func (pm *Loader) Init() {
+	pm.Plugins = make(map[string]*wrapPlugin, 10)
 
 	err := pm.ReloadPlugins()
-
 	if len(pm.Plugins) == 0 {
 		util.Logger().Warnf(err, "no any plugin has been loaded.")
 	}
 }
 
-func (pm *PluginManager) ReloadPlugins() error {
+func (pm *Loader) ReloadPlugins() error {
 	dir := os.ExpandEnv(pm.Dir)
 	if len(dir) == 0 {
 		dir, _ = os.Getwd()
@@ -61,58 +67,78 @@ func (pm *PluginManager) ReloadPlugins() error {
 		return err
 	}
 
-	nameRegex := `([A-Za-z0-9_.-]+)_plugin.so$`
-	regex, err := regexp.Compile(nameRegex)
-	if err != nil {
-		return err
-	}
-
 	for _, file := range files {
 		if !file.Mode().IsRegular() {
 			continue
 		}
+
 		submatchs := regex.FindStringSubmatch(file.Name())
-		if len(submatchs) >= 2 {
-			// golang 1.8+ feature
-			pluginFileFullPath := filepath.Join(dir, file.Name())
-			p, err := plugin.Open(pluginFileFullPath)
-			util.Logger().Debugf("load plugin '%s'. path: %s, result: %s",
-				submatchs[1], pluginFileFullPath, err)
-			if err != nil {
-				return fmt.Errorf("load plugin '%s' error for %s", submatchs[1], err.Error())
-			}
-			util.Logger().Infof("load plugin '%s' successfully.", submatchs[1])
-			pm.Plugins[submatchs[1]] = p
+		if len(submatchs) < 2 {
+			continue
 		}
+
+		// golang 1.8+ feature
+		pluginFileFullPath := filepath.Join(dir, file.Name())
+		p, err := plugin.Open(pluginFileFullPath)
+		if err != nil {
+			return fmt.Errorf("load plugin '%s' error for %s", submatchs[1], err.Error())
+		}
+		util.Logger().Infof("load plugin '%s' successfully.", submatchs[1])
+
+		pm.mux.Lock()
+		pm.Plugins[submatchs[1]] = &wrapPlugin{p, make(map[string]plugin.Symbol, 10)}
+		pm.mux.Unlock()
 	}
 	return nil
 }
 
-func (pm *PluginManager) Find(pluginName, funcName string) (plugin.Symbol, error) {
-	p, ok := pm.Plugins[pluginName]
+func (pm *Loader) Find(pluginName, funcName string) (plugin.Symbol, error) {
+	pm.mux.RLock()
+	w, ok := pm.Plugins[pluginName]
 	if !ok {
+		pm.mux.RUnlock()
 		return nil, fmt.Errorf("can not find plugin '%s'.", pluginName)
 	}
-	f, err := p.Lookup(funcName)
+
+	f, ok := w.funcs[funcName]
+	if ok {
+		pm.mux.RUnlock()
+		return f, nil
+	}
+	pm.mux.RUnlock()
+
+	pm.mux.Lock()
+	var err error
+	f, err = w.p.Lookup(funcName)
 	if err != nil {
+		pm.mux.Unlock()
 		return nil, err
 	}
+	w.funcs[funcName] = f
+	pm.mux.Unlock()
 	return f, nil
 }
 
+func (pm *Loader) Exist(pluginName string) bool {
+	pm.mux.RLock()
+	_, ok := pm.Plugins[pluginName]
+	pm.mux.RUnlock()
+	return ok
+}
+
 func SetPluginDir(dir string) {
-	pluginManager.Dir = dir
+	loader.Dir = dir
 }
 
-func GetPluginManager() *PluginManager {
-	once.Do(pluginManager.Init)
-	return &pluginManager
+func PluginLoader() *Loader {
+	once.Do(loader.Init)
+	return &loader
 }
 
 func Reload() error {
-	return GetPluginManager().ReloadPlugins()
+	return PluginLoader().ReloadPlugins()
 }
 
 func FindFunc(pluginName, funcName string) (plugin.Symbol, error) {
-	return GetPluginManager().Find(pluginName, funcName)
+	return PluginLoader().Find(pluginName, funcName)
 }
diff --git a/pkg/plugin/loader_test.go b/pkg/plugin/loader_test.go
new file mode 100644
index 00000000..d969f442
--- /dev/null
+++ b/pkg/plugin/loader_test.go
@@ -0,0 +1,102 @@
+/*
+ * 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 plugin
+
+import (
+	"fmt"
+	pg "plugin"
+	"testing"
+)
+
+func TestLoader_Init(t *testing.T) {
+	defer func() {
+		if err := recover(); err != nil {
+			fmt.Printf(`TestLoader_Init failed, %v`, err)
+			t.FailNow()
+		}
+	}()
+	loader := Loader{}
+	loader.Init()
+}
+
+func TestLoader_ReloadPlugins(t *testing.T) {
+	loader := Loader{}
+	loader.Init()
+	err := loader.ReloadPlugins()
+	if err != nil {
+		fmt.Printf(`TestLoader_ReloadPlugins failed, %s`, err.Error())
+		t.FailNow()
+	}
+
+	loader.Dir = "xxx"
+	err = loader.ReloadPlugins()
+	if err == nil {
+		fmt.Printf(`TestLoader_ReloadPlugins failed`)
+		t.FailNow()
+	}
+}
+
+func TestLoader_Exist(t *testing.T) {
+	loader := Loader{}
+	loader.Init()
+	b := loader.Exist("")
+	if b {
+		fmt.Printf(`TestLoader_Exist failed`)
+		t.FailNow()
+	}
+}
+
+func TestLoader_Find(t *testing.T) {
+	loader := Loader{}
+	loader.Init()
+	f, err := loader.Find("", "")
+	if err == nil || f != nil {
+		fmt.Printf(`TestLoader_Find failed`)
+		t.FailNow()
+	}
+
+	loader.Plugins["a"] = &wrapPlugin{&pg.Plugin{}, make(map[string]pg.Symbol)}
+	f, err = loader.Find("a", "")
+	if err == nil || f != nil {
+		fmt.Printf(`TestLoader_Find failed`)
+		t.FailNow()
+	}
+}
+
+func TestSetPluginDir(t *testing.T) {
+	SetPluginDir("")
+}
+
+func TestPluginLoader(t *testing.T) {
+	loader := PluginLoader()
+	if loader == nil {
+		fmt.Printf(`TestPluginLoader failed`)
+		t.FailNow()
+	}
+
+	err := Reload()
+	if err != nil {
+		fmt.Printf(`TestPluginLoader Reload failed, %s`, err)
+		t.FailNow()
+	}
+
+	f, err := FindFunc("", "")
+	if err == nil || f != nil {
+		fmt.Printf(`TestPluginLoader FindFunc failed`)
+		t.FailNow()
+	}
+}
diff --git a/server/bootstrap/bootstrap.go b/server/bootstrap/bootstrap.go
index c32acb41..5c50e651 100644
--- a/server/bootstrap/bootstrap.go
+++ b/server/bootstrap/bootstrap.go
@@ -35,10 +35,9 @@ import _ "github.com/apache/incubator-servicecomb-service-center/server/plugin/i
 
 // auth
 import _ "github.com/apache/incubator-servicecomb-service-center/server/plugin/infra/auth/buildin"
-import _ "github.com/apache/incubator-servicecomb-service-center/server/plugin/infra/auth/dynamic"
 
 // uuid
-import _ "github.com/apache/incubator-servicecomb-service-center/server/plugin/infra/uuid/dynamic"
+import _ "github.com/apache/incubator-servicecomb-service-center/server/plugin/infra/uuid/buildin"
 
 // module
 import _ "github.com/apache/incubator-servicecomb-service-center/server/govern"
diff --git a/server/govern/govern_suite_test.go b/server/govern/govern_suite_test.go
index b8063c35..8a71d2ee 100644
--- a/server/govern/govern_suite_test.go
+++ b/server/govern/govern_suite_test.go
@@ -22,7 +22,7 @@ import (
 	"github.com/apache/incubator-servicecomb-service-center/server/govern"
 	_ "github.com/apache/incubator-servicecomb-service-center/server/plugin/infra/quota/buildin"
 	_ "github.com/apache/incubator-servicecomb-service-center/server/plugin/infra/registry/etcd"
-	_ "github.com/apache/incubator-servicecomb-service-center/server/plugin/infra/uuid/dynamic"
+	_ "github.com/apache/incubator-servicecomb-service-center/server/plugin/infra/uuid/buildin"
 	"github.com/apache/incubator-servicecomb-service-center/server/service"
 	. "github.com/onsi/ginkgo"
 	"github.com/onsi/ginkgo/reporters"
diff --git a/server/plugin/infra/auth/buildin/buildin.go b/server/plugin/infra/auth/buildin/buildin.go
index 3592f380..027225ed 100644
--- a/server/plugin/infra/auth/buildin/buildin.go
+++ b/server/plugin/infra/auth/buildin/buildin.go
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package dynamic
+package buildin
 
 import (
 	mgr "github.com/apache/incubator-servicecomb-service-center/server/plugin"
@@ -22,7 +22,7 @@ import (
 )
 
 func init() {
-	mgr.RegisterPlugin(mgr.Plugin{mgr.STATIC, mgr.AUTH, "buildin", New})
+	mgr.RegisterPlugin(mgr.Plugin{mgr.AUTH, "buildin", New})
 }
 
 func New() mgr.PluginInstance {
@@ -33,5 +33,10 @@ type BuildInAuth struct {
 }
 
 func (ba *BuildInAuth) Identify(r *http.Request) error {
+	df, ok := mgr.DynamicPluginFunc(mgr.AUTH, "Identify").(func(r *http.Request) error)
+	if ok {
+		return df(r)
+	}
+
 	return nil
 }
diff --git a/server/plugin/infra/quota/buildin/buildin.go b/server/plugin/infra/quota/buildin/buildin.go
index 018a845b..d7082916 100644
--- a/server/plugin/infra/quota/buildin/buildin.go
+++ b/server/plugin/infra/quota/buildin/buildin.go
@@ -21,13 +21,13 @@ import (
 	"github.com/apache/incubator-servicecomb-service-center/pkg/util"
 	"github.com/apache/incubator-servicecomb-service-center/server/core"
 	"github.com/apache/incubator-servicecomb-service-center/server/core/backend/store"
+	scerr "github.com/apache/incubator-servicecomb-service-center/server/error"
 	"github.com/apache/incubator-servicecomb-service-center/server/infra/quota"
 	"github.com/apache/incubator-servicecomb-service-center/server/infra/registry"
 	mgr "github.com/apache/incubator-servicecomb-service-center/server/plugin"
 	serviceUtil "github.com/apache/incubator-servicecomb-service-center/server/service/util"
 	"golang.org/x/net/context"
 	"strings"
-	scerr "github.com/apache/incubator-servicecomb-service-center/server/error"
 )
 
 const (
@@ -42,7 +42,7 @@ func init() {
 	core.SchemaIdRule.Length = SCHEMA_NUM_MAX_LIMIT_PER_SERVICE
 	core.TagRule.Length = TAG_NUM_MAX_LIMIT_PER_SERVICE
 
-	mgr.RegisterPlugin(mgr.Plugin{mgr.STATIC, mgr.QUOTA, "buildin", New})
+	mgr.RegisterPlugin(mgr.Plugin{mgr.QUOTA, "buildin", New})
 }
 
 func New() mgr.PluginInstance {
@@ -54,6 +54,11 @@ type BuildInQuota struct {
 
 //????sourceType serviceinstance servicetype
 func (q *BuildInQuota) Apply4Quotas(ctx context.Context, res *quota.ApplyQuotaResource) *quota.ApplyQuotaResult {
+	df, ok := mgr.DynamicPluginFunc(mgr.QUOTA, "Apply4Quotas").(func(context.Context, *quota.ApplyQuotaResource) *quota.ApplyQuotaResult)
+	if ok {
+		return df(ctx, res)
+	}
+
 	data := &QuotaApplyData{
 		domain:    strings.Split(res.DomainProject, "/")[0],
 		quotaSize: res.QuotaSize,
@@ -70,6 +75,11 @@ func (q *BuildInQuota) Apply4Quotas(ctx context.Context, res *quota.ApplyQuotaRe
 
 //????????????
 func (q *BuildInQuota) RemandQuotas(ctx context.Context, quotaType quota.ResourceType) {
+	df, ok := mgr.DynamicPluginFunc(mgr.QUOTA, "RemandQuotas").(func(context.Context, quota.ResourceType))
+	if ok {
+		df(ctx, quotaType)
+		return
+	}
 }
 
 func ResourceLimitHandler(ctx context.Context, res *quota.ApplyQuotaResource) *quota.ApplyQuotaResult {
@@ -211,7 +221,7 @@ func serviceQuotaCheck(ctx context.Context, data *QuotaApplyData) *quota.ApplyQu
 		util.Logger().Errorf(err, mes)
 		return quota.NewApplyQuotaResult(nil, scerr.NewError(scerr.ErrNotEnoughQuota, mes))
 	}
-	return quota.NewApplyQuotaResult(nil,nil)
+	return quota.NewApplyQuotaResult(nil, nil)
 }
 
 func getServiceMaxLimit() int64 {
diff --git a/server/plugin/infra/quota/unlimit/unlimit.go b/server/plugin/infra/quota/unlimit/unlimit.go
index 319d8cf3..f8212e42 100644
--- a/server/plugin/infra/quota/unlimit/unlimit.go
+++ b/server/plugin/infra/quota/unlimit/unlimit.go
@@ -25,7 +25,7 @@ import (
 )
 
 func init() {
-	mgr.RegisterPlugin(mgr.Plugin{mgr.STATIC, mgr.QUOTA, "unlimit", New})
+	mgr.RegisterPlugin(mgr.Plugin{mgr.QUOTA, "unlimit", New})
 
 	quataType := beego.AppConfig.DefaultString("quota_plugin", "")
 	if quataType != "unlimit" {
diff --git a/server/plugin/infra/registry/buildin/buildin.go b/server/plugin/infra/registry/buildin/buildin.go
index 302dd563..3794da00 100644
--- a/server/plugin/infra/registry/buildin/buildin.go
+++ b/server/plugin/infra/registry/buildin/buildin.go
@@ -25,7 +25,7 @@ import (
 )
 
 func init() {
-	mgr.RegisterPlugin(mgr.Plugin{mgr.STATIC, mgr.REGISTRY, "buildin", NewRegistry})
+	mgr.RegisterPlugin(mgr.Plugin{mgr.REGISTRY, "buildin", NewRegistry})
 }
 
 var noPluginErr = fmt.Errorf("register center plugin does not exist")
diff --git a/server/plugin/infra/registry/embededetcd/embededetcd.go b/server/plugin/infra/registry/embededetcd/embededetcd.go
index 03b85851..4b941bce 100644
--- a/server/plugin/infra/registry/embededetcd/embededetcd.go
+++ b/server/plugin/infra/registry/embededetcd/embededetcd.go
@@ -44,7 +44,7 @@ var embedTLSConfig *tls.Config
 const START_MANAGER_SERVER_TIMEOUT = 60
 
 func init() {
-	mgr.RegisterPlugin(mgr.Plugin{mgr.STATIC, mgr.REGISTRY, "embeded_etcd", getEmbedInstance})
+	mgr.RegisterPlugin(mgr.Plugin{mgr.REGISTRY, "embeded_etcd", getEmbedInstance})
 }
 
 type EtcdEmbed struct {
diff --git a/server/plugin/infra/registry/etcd/etcd.go b/server/plugin/infra/registry/etcd/etcd.go
index e0b79353..d848eb92 100644
--- a/server/plugin/infra/registry/etcd/etcd.go
+++ b/server/plugin/infra/registry/etcd/etcd.go
@@ -42,7 +42,7 @@ const (
 var clientTLSConfig *tls.Config
 
 func init() {
-	mgr.RegisterPlugin(mgr.Plugin{mgr.STATIC, mgr.REGISTRY, "etcd", NewRegistry})
+	mgr.RegisterPlugin(mgr.Plugin{mgr.REGISTRY, "etcd", NewRegistry})
 }
 
 type EtcdClient struct {
diff --git a/server/plugin/infra/security/buildin/buildin.go b/server/plugin/infra/security/buildin/buildin.go
index dff36524..6e29ed47 100644
--- a/server/plugin/infra/security/buildin/buildin.go
+++ b/server/plugin/infra/security/buildin/buildin.go
@@ -21,7 +21,7 @@ import (
 )
 
 func init() {
-	mgr.RegisterPlugin(mgr.Plugin{mgr.STATIC, mgr.CIPHER, "buildin", New})
+	mgr.RegisterPlugin(mgr.Plugin{mgr.CIPHER, "buildin", New})
 }
 
 func New() mgr.PluginInstance {
@@ -32,9 +32,17 @@ type DefaultCipher struct {
 }
 
 func (c *DefaultCipher) Encrypt(src string) (string, error) {
+	df, ok := mgr.DynamicPluginFunc(mgr.CIPHER, "Encrypt").(func(src string) (string, error))
+	if ok {
+		return df(src)
+	}
 	return src, nil
 }
 
 func (c *DefaultCipher) Decrypt(src string) (string, error) {
+	df, ok := mgr.DynamicPluginFunc(mgr.CIPHER, "Decrypt").(func(src string) (string, error))
+	if ok {
+		return df(src)
+	}
 	return src, nil
 }
diff --git a/server/plugin/infra/auth/dynamic/dynamic.go b/server/plugin/infra/uuid/buildin/buildin.go
similarity index 54%
rename from server/plugin/infra/auth/dynamic/dynamic.go
rename to server/plugin/infra/uuid/buildin/buildin.go
index c966b061..e54ff8c7 100644
--- a/server/plugin/infra/auth/dynamic/dynamic.go
+++ b/server/plugin/infra/uuid/buildin/buildin.go
@@ -14,47 +14,37 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package dynamic
+
+package buildin
 
 import (
-	"github.com/apache/incubator-servicecomb-service-center/pkg/plugin"
-	"github.com/apache/incubator-servicecomb-service-center/pkg/util"
+	"github.com/apache/incubator-servicecomb-service-center/pkg/uuid"
 	mgr "github.com/apache/incubator-servicecomb-service-center/server/plugin"
-	"net/http"
 )
 
-var authFunc func(r *http.Request) error
-
 func init() {
-	f := findAuthFunc("Identify")
-	if f == nil {
-		return
-	}
-
-	authFunc = f
-	mgr.RegisterPlugin(mgr.Plugin{mgr.DYNAMIC, mgr.AUTH, "dynamic", New})
+	mgr.RegisterPlugin(mgr.Plugin{mgr.UUID, "buildin", New})
 }
 
-func findAuthFunc(funcName string) func(r *http.Request) error {
-	ff, err := plugin.FindFunc("auth", funcName)
-	if err != nil {
-		return nil
-	}
-	f, ok := ff.(func(*http.Request) error)
-	if !ok {
-		util.Logger().Warnf(nil, "unexpected function '%s' format found in plugin 'auth'.", funcName)
-		return nil
-	}
-	return f
+func New() mgr.PluginInstance {
+	return &BuildinUUID{}
 }
 
-func New() mgr.PluginInstance {
-	return &DynamicAuth{}
+type BuildinUUID struct {
 }
 
-type DynamicAuth struct {
+func (du *BuildinUUID) GetServiceId() string {
+	df, ok := mgr.DynamicPluginFunc(mgr.UUID, "GetServiceId").(func() string)
+	if ok {
+		return df()
+	}
+	return uuid.GenerateUuid()
 }
 
-func (da *DynamicAuth) Identify(r *http.Request) error {
-	return authFunc(r)
+func (du *BuildinUUID) GetInstanceId() string {
+	df, ok := mgr.DynamicPluginFunc(mgr.UUID, "GetInstanceId").(func() string)
+	if ok {
+		return df()
+	}
+	return uuid.GenerateUuid()
 }
diff --git a/server/plugin/infra/uuid/dynamic/dynamic.go b/server/plugin/infra/uuid/dynamic/dynamic.go
deleted file mode 100644
index 1dc1fbad..00000000
--- a/server/plugin/infra/uuid/dynamic/dynamic.go
+++ /dev/null
@@ -1,69 +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 dynamic
-
-import (
-	"github.com/apache/incubator-servicecomb-service-center/pkg/plugin"
-	"github.com/apache/incubator-servicecomb-service-center/pkg/util"
-	"github.com/apache/incubator-servicecomb-service-center/pkg/uuid"
-	mgr "github.com/apache/incubator-servicecomb-service-center/server/plugin"
-)
-
-var (
-	serviceIdFunc  func() string
-	instanceIdFunc func() string
-)
-
-func init() {
-	serviceIdFunc = findUuidFunc("GetServiceId")
-	instanceIdFunc = findUuidFunc("GetInstanceId")
-
-	mgr.RegisterPlugin(mgr.Plugin{mgr.DYNAMIC, mgr.UUID, "dynamic", New})
-}
-
-func buildinUuidFunc() string {
-	return uuid.GenerateUuid()
-}
-
-func findUuidFunc(funcName string) func() string {
-	ff, err := plugin.FindFunc("uuid", funcName)
-	if err != nil {
-		return buildinUuidFunc
-	}
-	f, ok := ff.(func() string)
-	if !ok {
-		util.Logger().Warnf(nil, "unexpected function '%s' format found in plugin 'uuid'.", funcName)
-		return buildinUuidFunc
-	}
-	return f
-}
-
-func New() mgr.PluginInstance {
-	return &DynamicUUID{}
-}
-
-type DynamicUUID struct {
-}
-
-func (du *DynamicUUID) GetServiceId() string {
-	return serviceIdFunc()
-}
-
-func (du *DynamicUUID) GetInstanceId() string {
-	return instanceIdFunc()
-}
diff --git a/server/plugin/plugin.go b/server/plugin/plugin.go
index 11fbe88f..02ffa064 100644
--- a/server/plugin/plugin.go
+++ b/server/plugin/plugin.go
@@ -18,6 +18,7 @@ package plugin
 
 import (
 	"fmt"
+	"github.com/apache/incubator-servicecomb-service-center/pkg/plugin"
 	"github.com/apache/incubator-servicecomb-service-center/pkg/util"
 	"github.com/apache/incubator-servicecomb-service-center/server/infra/auditlog"
 	"github.com/apache/incubator-servicecomb-service-center/server/infra/auth"
@@ -26,13 +27,11 @@ import (
 	"github.com/apache/incubator-servicecomb-service-center/server/infra/security"
 	"github.com/apache/incubator-servicecomb-service-center/server/infra/uuid"
 	"github.com/astaxie/beego"
+	pg "plugin"
 	"sync"
 )
 
-const (
-	STATIC PluginType = iota
-	DYNAMIC
-)
+const BUILDIN = "buildin"
 
 const (
 	UUID PluginName = iota
@@ -59,15 +58,6 @@ func init() {
 	pluginMgr.Initialize()
 }
 
-type PluginType int
-
-func (pt PluginType) String() string {
-	if pt == DYNAMIC {
-		return "dynamic"
-	}
-	return "static"
-}
-
 type PluginName int
 
 func (pn PluginName) String() string {
@@ -78,7 +68,6 @@ func (pn PluginName) String() string {
 }
 
 type Plugin struct {
-	Type  PluginType
 	PName PluginName
 	Name  string
 	New   func() PluginInstance
@@ -87,6 +76,7 @@ type Plugin struct {
 type PluginInstance interface{}
 
 type wrapInstance struct {
+	dynamic  bool
 	instance PluginInstance
 	lock     sync.RWMutex
 }
@@ -121,7 +111,7 @@ func (pm *PluginManager) Register(p Plugin) {
 	}
 	m[p.Name] = &p
 	pm.plugins[p.PName] = m
-	util.Logger().Infof("%s load '%s' plugin named '%s'", p.Type, p.PName, p.Name)
+	util.Logger().Infof("load '%s' plugin named '%s'", p.PName, p.Name)
 }
 
 func (pm *PluginManager) Get(pn PluginName, name string) *Plugin {
@@ -146,33 +136,42 @@ func (pm *PluginManager) Instance(pn PluginName) PluginInstance {
 		wi.lock.Unlock()
 		return wi.instance
 	}
-	wi.instance = pm.New(pn)
+	pm.New(pn)
 	wi.lock.Unlock()
 
 	return wi.instance
 }
 
-func (pm *PluginManager) New(pn PluginName) PluginInstance {
-	var f func() PluginInstance
+func (pm *PluginManager) New(pn PluginName) {
+	var (
+		title = "static"
+		f     func() PluginInstance
+	)
+
+	wi := pm.instances[pn]
 	p := pm.existDynamicPlugin(pn)
 	if p != nil {
+		wi.dynamic = true
+		title = "dynamic"
 		f = p.New
 	} else {
+		wi.dynamic = false
 		m, ok := pm.plugins[pn]
 		if !ok {
-			return nil
+			return
 		}
 
-		name := beego.AppConfig.DefaultString(pn.String()+"_plugin", "buildin")
+		name := beego.AppConfig.DefaultString(pn.String()+"_plugin", BUILDIN)
 		p, ok = m[name]
 		if !ok {
-			return nil
+			return
 		}
 
 		f = p.New
 	}
-	util.Logger().Infof("new '%s' plugin '%s' instance", p.PName, p.Name)
-	return f()
+	util.Logger().Infof("new '%s' instance from '%s' %s plugin", p.Name, p.PName, title)
+
+	wi.instance = f()
 }
 
 func (pm *PluginManager) Reload(pn PluginName) {
@@ -187,10 +186,8 @@ func (pm *PluginManager) existDynamicPlugin(pn PluginName) *Plugin {
 	if !ok {
 		return nil
 	}
-	for _, p := range m {
-		if p.Type == DYNAMIC {
-			return p
-		}
+	if plugin.PluginLoader().Exist(pn.String()) {
+		return m[BUILDIN]
 	}
 	return nil
 }
@@ -226,3 +223,15 @@ func Plugins() *PluginManager {
 func RegisterPlugin(p Plugin) {
 	Plugins().Register(p)
 }
+
+func DynamicPluginFunc(pn PluginName, funcName string) pg.Symbol {
+	if wi := Plugins().instances[pn]; !wi.dynamic {
+		return nil
+	}
+
+	f, err := plugin.FindFunc(pn.String(), funcName)
+	if err != nil {
+		util.Logger().Errorf(err, "plugin '%s': not implemented function '%s'.", pn, funcName)
+	}
+	return f
+}
diff --git a/server/rest/controller/v4/main_controller.go b/server/rest/controller/v4/main_controller.go
index 3790bd20..d2af4d4e 100644
--- a/server/rest/controller/v4/main_controller.go
+++ b/server/rest/controller/v4/main_controller.go
@@ -28,6 +28,8 @@ import (
 	"net/http"
 )
 
+var resultJSON []byte
+
 const API_VERSION = "4.0.0"
 
 type Result struct {
@@ -41,6 +43,12 @@ type MainService struct {
 }
 
 func init() {
+	result := Result{
+		version.Ver(),
+		API_VERSION,
+		core.ServerInfo.Config,
+	}
+	resultJSON, _ = json.Marshal(result)
 }
 
 func (this *MainService) URLPatterns() []rest.Route {
@@ -64,12 +72,6 @@ func (this *MainService) ClusterHealth(w http.ResponseWriter, r *http.Request) {
 }
 
 func (this *MainService) GetVersion(w http.ResponseWriter, r *http.Request) {
-	result := Result{
-		version.Ver(),
-		API_VERSION,
-		core.ServerInfo.Config,
-	}
-	resultJSON, _ := json.Marshal(result)
 	w.Header().Set("Content-Type", "application/json;charset=utf-8")
 	w.Write(resultJSON)
 }
diff --git a/server/service/event/dependency_event_handler.go b/server/service/event/dependency_event_handler.go
index 6789a143..00ea7908 100644
--- a/server/service/event/dependency_event_handler.go
+++ b/server/service/event/dependency_event_handler.go
@@ -85,18 +85,6 @@ func (h *DependencyEventHandler) loop() {
 					retry()
 					continue
 				}
-			case <-time.After(10 * time.Second):
-				key := core.GetServiceDependencyQueueRootKey("")
-				resp, _ := store.Store().DependencyQueue().Search(context.Background(),
-					registry.WithStrKey(key),
-					registry.WithPrefix(),
-					registry.WithCountOnly(),
-					registry.WithCacheOnly())
-				if resp != nil && resp.Count > 0 {
-					util.Logger().Infof("wait for dependency event timed out(10s) and found %d items still in queue",
-						resp.Count)
-					h.signals.Put(context.Background(), struct{}{})
-				}
 			}
 		}
 	})
diff --git a/server/service/service_suite_test.go b/server/service/service_suite_test.go
index e23ad935..d9c0cb9e 100644
--- a/server/service/service_suite_test.go
+++ b/server/service/service_suite_test.go
@@ -21,7 +21,7 @@ import (
 	pb "github.com/apache/incubator-servicecomb-service-center/server/core/proto"
 	_ "github.com/apache/incubator-servicecomb-service-center/server/plugin/infra/quota/buildin"
 	_ "github.com/apache/incubator-servicecomb-service-center/server/plugin/infra/registry/etcd"
-	_ "github.com/apache/incubator-servicecomb-service-center/server/plugin/infra/uuid/dynamic"
+	_ "github.com/apache/incubator-servicecomb-service-center/server/plugin/infra/uuid/buildin"
 	"github.com/apache/incubator-servicecomb-service-center/server/service"
 	. "github.com/onsi/ginkgo"
 	"github.com/onsi/ginkgo/reporters"


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services