func (c *Coordinator) Reload() error {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	logger := log.With(c.logger, "file", c.configFilePath)
	level.Info(logger).Log("msg", "Loading configuration file")
	if err := c.loadFromFile(); err != nil {
		level.Error(logger).Log(
			"msg", "Loading configuration file failed",
			"err", err,
		)
		return err
	}
	level.Info(logger).Log("msg", "Completed loading of configuration file")
	if err := c.notifySubscribers(); err != nil {
		logger.Log("msg", "one or more config change subscribers failed to apply new config", "err", err)
		return err
	}
	return nil
}
Reload triggers a configuration reload from file and notifies all
configuration change subscribers.
package config
import (
	"sync"
	"github.com/go-kit/log"
	"github.com/go-kit/log/level"
)
type Coordinator struct {
	configFilePath string
	logger         log.Logger
	mutex       sync.Mutex
	config      *Config
	subscribers []func(*Config) error
}
func NewCoordinator(configFilePath string, l log.Logger) *Coordinator {
	c := &Coordinator{
		configFilePath: configFilePath,
		logger:         l,
	}
	return c
}
func (c *Coordinator) Subscribe(ss ...func(*Config) error) {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	c.subscribers = append(c.subscribers, ss...)
}
func (c *Coordinator) notifySubscribers() error {
	for _, s := range c.subscribers {
		if err := s(c.config); err != nil {
			return err
		}
	}
	return nil
}
func (c *Coordinator) loadFromFile() error {
	conf, err := LoadFile(c.configFilePath)
	if err != nil {
		return err
	}
	c.config = conf
	return nil
}