diff --git a/plugins/plugins.go b/plugins/plugins.go index 87a8eba..f369053 100644 --- a/plugins/plugins.go +++ b/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.