|
@@ -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.
|