Ver Fonte

Merge pull request #15684 from ibuildthecloud/dont-sync

Don't globally lock on driver initialization
Brian Goff há 10 anos atrás
pai
commit
7f46dc03d5
2 ficheiros alterados com 35 adições e 14 exclusões
  1. 28 13
      pkg/plugins/plugins.go
  2. 7 1
      volume/drivers/extpoint.go

+ 28 - 13
pkg/plugins/plugins.go

@@ -63,6 +63,9 @@ type Plugin struct {
 	Client *Client `json:"-"`
 	// Manifest of the plugin (see above)
 	Manifest *Manifest `json:"-"`
+
+	activatErr   error
+	activateOnce sync.Once
 }
 
 func newLocalPlugin(name, addr string) *Plugin {
@@ -74,6 +77,13 @@ func newLocalPlugin(name, addr string) *Plugin {
 }
 
 func (p *Plugin) activate() error {
+	p.activateOnce.Do(func() {
+		p.activatErr = p.activateWithLock()
+	})
+	return p.activatErr
+}
+
+func (p *Plugin) activateWithLock() error {
 	c, err := NewClient(p.Addr, p.TLSConfig)
 	if err != nil {
 		return err
@@ -99,32 +109,37 @@ func (p *Plugin) activate() error {
 }
 
 func load(name string) (*Plugin, error) {
+	storage.Lock()
 	registry := newLocalRegistry()
 	pl, err := registry.Plugin(name)
+	if err == nil {
+		storage.plugins[name] = pl
+	}
+	storage.Unlock()
+
 	if err != nil {
 		return nil, err
 	}
-	if err := pl.activate(); err != nil {
-		return nil, err
+
+	err = pl.activate()
+
+	if err != nil {
+		storage.Lock()
+		delete(storage.plugins, name)
+		storage.Unlock()
 	}
-	return pl, nil
+
+	return pl, err
 }
 
 func get(name string) (*Plugin, error) {
 	storage.Lock()
-	defer storage.Unlock()
 	pl, ok := storage.plugins[name]
+	storage.Unlock()
 	if ok {
-		return pl, nil
+		return pl, pl.activate()
 	}
-	pl, err := load(name)
-	if err != nil {
-		return nil, err
-	}
-
-	logrus.Debugf("Plugin: %v", pl)
-	storage.plugins[name] = pl
-	return pl, nil
+	return load(name)
 }
 
 // Get returns the plugin given the specified name and requested implementation.

+ 7 - 1
volume/drivers/extpoint.go

@@ -51,8 +51,8 @@ func Unregister(name string) bool {
 // there is a VolumeDriver plugin available with the given name.
 func Lookup(name string) (volume.Driver, error) {
 	drivers.Lock()
-	defer drivers.Unlock()
 	ext, ok := drivers.extensions[name]
+	drivers.Unlock()
 	if ok {
 		return ext, nil
 	}
@@ -61,6 +61,12 @@ func Lookup(name string) (volume.Driver, error) {
 		return nil, fmt.Errorf("Error looking up volume plugin %s: %v", name, err)
 	}
 
+	drivers.Lock()
+	defer drivers.Unlock()
+	if ext, ok := drivers.extensions[name]; ok {
+		return ext, nil
+	}
+
 	d := NewVolumeDriver(name, pl.Client)
 	drivers.extensions[name] = d
 	return d, nil