Don't globally lock on driver initialization

This patch makes it such that plugin initialization is synchronized
based on the plugin name and not globally

Signed-off-by: Darren Shepherd <darren@rancher.com>
This commit is contained in:
Darren Shepherd 2015-08-18 22:04:22 -07:00
parent f192bc6f68
commit bf81718eba

View file

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