summaryrefslogtreecommitdiffstats
path: root/plugin/environment.go
diff options
context:
space:
mode:
Diffstat (limited to 'plugin/environment.go')
-rw-r--r--plugin/environment.go88
1 files changed, 41 insertions, 47 deletions
diff --git a/plugin/environment.go b/plugin/environment.go
index 7adb0938d..7d639bdd7 100644
--- a/plugin/environment.go
+++ b/plugin/environment.go
@@ -34,8 +34,7 @@ type activePlugin struct {
// It is meant for use by the Mattermost server to manipulate, interact with and report on the set
// of active plugins.
type Environment struct {
- activePlugins map[string]activePlugin
- mutex sync.RWMutex
+ activePlugins sync.Map
logger *mlog.Logger
newAPIImpl apiImplCreatorFunc
pluginDir string
@@ -44,7 +43,6 @@ type Environment struct {
func NewEnvironment(newAPIImpl apiImplCreatorFunc, pluginDir string, webappPluginDir string, logger *mlog.Logger) (*Environment, error) {
return &Environment{
- activePlugins: make(map[string]activePlugin),
logger: logger,
newAPIImpl: newAPIImpl,
pluginDir: pluginDir,
@@ -83,28 +81,24 @@ func (env *Environment) Available() ([]*model.BundleInfo, error) {
// Returns a list of all currently active plugins within the environment.
func (env *Environment) Active() []*model.BundleInfo {
- env.mutex.RLock()
- defer env.mutex.RUnlock()
-
activePlugins := []*model.BundleInfo{}
- for _, p := range env.activePlugins {
- activePlugins = append(activePlugins, p.BundleInfo)
- }
+ env.activePlugins.Range(func(key, value interface{}) bool {
+ activePlugins = append(activePlugins, value.(activePlugin).BundleInfo)
+
+ return true
+ })
return activePlugins
}
// IsActive returns true if the plugin with the given id is active.
func (env *Environment) IsActive(id string) bool {
- _, ok := env.activePlugins[id]
+ _, ok := env.activePlugins.Load(id)
return ok
}
// Statuses returns a list of plugin statuses representing the state of every plugin
func (env *Environment) Statuses() (model.PluginStatuses, error) {
- env.mutex.RLock()
- defer env.mutex.RUnlock()
-
plugins, err := env.Available()
if err != nil {
return nil, errors.Wrap(err, "unable to get plugin statuses")
@@ -118,8 +112,8 @@ func (env *Environment) Statuses() (model.PluginStatuses, error) {
}
pluginState := model.PluginStateNotRunning
- if plugin, ok := env.activePlugins[plugin.Manifest.Id]; ok {
- pluginState = plugin.State
+ if plugin, ok := env.activePlugins.Load(plugin.Manifest.Id); ok {
+ pluginState = plugin.(activePlugin).State
}
status := &model.PluginStatus{
@@ -139,11 +133,9 @@ func (env *Environment) Statuses() (model.PluginStatuses, error) {
// Activate activates the plugin with the given id.
func (env *Environment) Activate(id string) (reterr error) {
- env.mutex.Lock()
- defer env.mutex.Unlock()
// Check if we are already active
- if _, ok := env.activePlugins[id]; ok {
+ if _, ok := env.activePlugins.Load(id); ok {
return nil
}
@@ -171,7 +163,7 @@ func (env *Environment) Activate(id string) (reterr error) {
} else {
activePlugin.State = model.PluginStateFailedToStart
}
- env.activePlugins[pluginInfo.Manifest.Id] = activePlugin
+ env.activePlugins.Store(pluginInfo.Manifest.Id, activePlugin)
}()
if pluginInfo.Manifest.Webapp != nil {
@@ -205,48 +197,49 @@ func (env *Environment) Activate(id string) (reterr error) {
// Deactivates the plugin with the given id.
func (env *Environment) Deactivate(id string) {
- env.mutex.Lock()
- defer env.mutex.Unlock()
-
- if activePlugin, ok := env.activePlugins[id]; !ok {
+ p, ok := env.activePlugins.Load(id)
+ if !ok {
return
- } else {
- delete(env.activePlugins, id)
- if activePlugin.supervisor != nil {
- if err := activePlugin.supervisor.Hooks().OnDeactivate(); err != nil {
- env.logger.Error("Plugin OnDeactivate() error", mlog.String("plugin_id", activePlugin.BundleInfo.Manifest.Id), mlog.Err(err))
- }
- activePlugin.supervisor.Shutdown()
+ }
+
+ env.activePlugins.Delete(id)
+
+ activePlugin := p.(activePlugin)
+ if activePlugin.supervisor != nil {
+ if err := activePlugin.supervisor.Hooks().OnDeactivate(); err != nil {
+ env.logger.Error("Plugin OnDeactivate() error", mlog.String("plugin_id", activePlugin.BundleInfo.Manifest.Id), mlog.Err(err))
}
+ activePlugin.supervisor.Shutdown()
}
}
// Shutdown deactivates all plugins and gracefully shuts down the environment.
func (env *Environment) Shutdown() {
- env.mutex.Lock()
- defer env.mutex.Unlock()
+ env.activePlugins.Range(func(key, value interface{}) bool {
+ activePlugin := value.(activePlugin)
- for _, activePlugin := range env.activePlugins {
if activePlugin.supervisor != nil {
if err := activePlugin.supervisor.Hooks().OnDeactivate(); err != nil {
env.logger.Error("Plugin OnDeactivate() error", mlog.String("plugin_id", activePlugin.BundleInfo.Manifest.Id), mlog.Err(err))
}
activePlugin.supervisor.Shutdown()
}
- }
- env.activePlugins = make(map[string]activePlugin)
- return
+
+ env.activePlugins.Delete(key)
+
+ return true
+ })
}
// HooksForPlugin returns the hooks API for the plugin with the given id.
//
// Consider using RunMultiPluginHook instead.
func (env *Environment) HooksForPlugin(id string) (Hooks, error) {
- env.mutex.RLock()
- defer env.mutex.RUnlock()
-
- if plug, ok := env.activePlugins[id]; ok && plug.supervisor != nil {
- return plug.supervisor.Hooks(), nil
+ if p, ok := env.activePlugins.Load(id); ok {
+ activePlugin := p.(activePlugin)
+ if activePlugin.supervisor != nil {
+ return activePlugin.supervisor.Hooks(), nil
+ }
}
return nil, fmt.Errorf("plugin not found: %v", id)
@@ -257,15 +250,16 @@ func (env *Environment) HooksForPlugin(id string) (Hooks, error) {
// If hookRunnerFunc returns false, iteration will not continue. The iteration order among active
// plugins is not specified.
func (env *Environment) RunMultiPluginHook(hookRunnerFunc multiPluginHookRunnerFunc, hookId int) {
- env.mutex.RLock()
- defer env.mutex.RUnlock()
+ env.activePlugins.Range(func(key, value interface{}) bool {
+ activePlugin := value.(activePlugin)
- for _, activePlugin := range env.activePlugins {
if activePlugin.supervisor == nil || !activePlugin.supervisor.Implements(hookId) {
- continue
+ return true
}
if !hookRunnerFunc(activePlugin.supervisor.Hooks()) {
- break
+ return false
}
- }
+
+ return true
+ })
}