maddy/module/instances.go
fox.cpp 0ddf540d35 Implement lazy initialization of module instances
It is correct fix for initialization order issue introduced in
https://github.com/emersion/maddy/pull/24.
2019-04-08 19:34:09 +03:00

69 lines
1.6 KiB
Go

package module
import (
"fmt"
"github.com/emersion/maddy/config"
"github.com/emersion/maddy/log"
)
var (
Instances = make(map[string]struct {
mod Module
cfg *config.Map
})
Initialized = make(map[string]bool)
)
// Register adds module instance to the global registry.
//
// Instnace name must be unique. Second RegisterInstance with same instance
// name will replace previous.
func RegisterInstance(inst Module, cfg *config.Map) {
Instances[inst.InstanceName()] = struct {
mod Module
cfg *config.Map
}{inst, cfg}
}
// GetUninitedInstance returns module instance from global registry.
//
// Nil is returned if no module instance with specified name is Instances.
//
// Note that this function may return uninitialized module. If you need to ensure
// that it is safe to interact with module instance - use GetInstance instead.
func GetUninitedInstance(name string) Module {
mod, ok := Instances[name]
if !ok {
return nil
}
return mod.mod
}
// GetInstance returns module instance from global registry, initializing it if
// necessary.
//
// Error is returned if module initialization fails or module instance does not
// exists.
func GetInstance(name string) (Module, error) {
mod, ok := Instances[name]
if !ok {
return nil, fmt.Errorf("unknown module instance: %s", name)
}
// Break circular dependencies.
if Initialized[name] {
log.Debugln("module init", mod.mod.Name(), name, "(lazy init skipped)")
return mod.mod, nil
}
log.Debugln("module init", mod.mod.Name(), name, "(lazy)")
Initialized[name] = true
if err := mod.mod.Init(mod.cfg); err != nil {
return mod.mod, err
}
return mod.mod, nil
}