You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by as...@apache.org on 2018/01/23 04:23:52 UTC

[incubator-servicecomb-service-center] branch master updated: SCB-276 Optimize plugins loader (#257)

This is an automated email from the ASF dual-hosted git repository.

asifdxtreme pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-service-center.git


The following commit(s) were added to refs/heads/master by this push:
     new eaee000  SCB-276 Optimize plugins loader (#257)
eaee000 is described below

commit eaee0005a10a4e2425be145ad640a952975d7d31
Author: little-cui <su...@qq.com>
AuthorDate: Tue Jan 23 12:23:50 2018 +0800

    SCB-276 Optimize plugins loader (#257)
    
    * Optimize plugins loader.
    
    (cherry picked from commit 824e66d)
    
    * Optimize plugins loader.
    
    * Optimize plugins loader.
    
    * Optimize plugins loader.
---
 pkg/plugin/loader.go                               |  94 ++++++++++++-------
 pkg/plugin/loader_test.go                          | 102 +++++++++++++++++++++
 server/bootstrap/bootstrap.go                      |   3 +-
 server/govern/govern_suite_test.go                 |   2 +-
 server/plugin/infra/auth/buildin/buildin.go        |   9 +-
 server/plugin/infra/quota/buildin/buildin.go       |  16 +++-
 server/plugin/infra/quota/unlimit/unlimit.go       |   2 +-
 server/plugin/infra/registry/buildin/buildin.go    |   2 +-
 .../infra/registry/embededetcd/embededetcd.go      |   2 +-
 server/plugin/infra/registry/etcd/etcd.go          |   2 +-
 server/plugin/infra/security/buildin/buildin.go    |  10 +-
 .../dynamic/dynamic.go => uuid/buildin/buildin.go} |  48 ++++------
 server/plugin/infra/uuid/dynamic/dynamic.go        |  69 --------------
 server/plugin/plugin.go                            |  63 +++++++------
 server/rest/controller/v4/main_controller.go       |  14 +--
 server/service/event/dependency_event_handler.go   |  12 ---
 server/service/service_suite_test.go               |   2 +-
 17 files changed, 261 insertions(+), 191 deletions(-)

diff --git a/pkg/plugin/loader.go b/pkg/plugin/loader.go
index 4a173e0..0306ef2 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 0000000..d969f44
--- /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 c32acb4..5c50e65 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 b8063c3..8a71d2e 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 3592f38..027225e 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 018a845..d708291 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 319d8cf..f8212e4 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 302dd56..3794da0 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 03b8585..4b941bc 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 e0b7935..d848eb9 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 dff3652..6e29ed4 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 c966b06..e54ff8c 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 1dc1fba..0000000
--- 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 11fbe88..02ffa06 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 3790bd2..d2af4d4 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 c91cb35..99808e1 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 e23ad93..d9c0cb9 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"

-- 
To stop receiving notification emails like this one, please contact
asifdxtreme@apache.org.