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:
parent
f192bc6f68
commit
bf81718eba
1 changed files with 28 additions and 13 deletions
|
@ -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.
|
||||||
|
|
Loading…
Reference in a new issue