package main import ( "reflect" "github.com/pkg/errors" ) // configuration captures the plugin's external configuration as exposed in the Mattermost server // configuration, as well as values computed from the configuration. type configuration struct { EnableGameStatus bool `json:"enable_game_status"` // Enable or disable game status updates KnownGames []string `json:"known_games"` // List of known game process names DisableIPv6 bool `json:"disable_ipv6"` // Disable IPv6; default is false } // Clone shallow copies the configuration. Your implementation may require a deep copy if // your configuration has reference types. func (c *configuration) Clone() *configuration { var clone = *c // Create a deep copy of the KnownGames slice clone.KnownGames = make([]string, len(c.KnownGames)) copy(clone.KnownGames, c.KnownGames) return &clone } // getConfiguration retrieves the active configuration under lock, making it safe to use // concurrently. The active configuration may change underneath the client of this method, but // the struct returned by this API call is considered immutable. func (p *Plugin) getConfiguration() *configuration { p.configurationLock.RLock() defer p.configurationLock.RUnlock() if p.configuration == nil { return &configuration{ DisableIPv6: false, // Default value for DisableIPv6 EnableGameStatus: true, // Default to enabled if you want this feature active by default KnownGames: []string{}, // Ensure this is initialized to avoid nil references } } return p.configuration } // setConfiguration replaces the active configuration under lock. func (p *Plugin) setConfiguration(configuration *configuration) { p.configurationLock.Lock() defer p.configurationLock.Unlock() if configuration != nil && p.configuration == configuration { if reflect.ValueOf(*configuration).NumField() == 0 { return } panic("setConfiguration called with the existing configuration") } p.configuration = configuration } // OnConfigurationChange is invoked when configuration changes may have been made. func (p *Plugin) OnConfigurationChange() error { var configuration = new(configuration) // Load the public configuration fields from the Mattermost server configuration. if err := p.API.LoadPluginConfiguration(configuration); err != nil { return errors.Wrap(err, "failed to load plugin configuration") } p.setConfiguration(configuration) return nil }