mirror of
https://github.com/foxcpp/maddy.git
synced 2025-04-05 05:57:39 +03:00
Make endpoint modules special
To support unusual configuration syntax, endpoint modules (imap, smtp,
etc) relied on rather awkward code using modName+instName+aliases as
arguments. This commit replaces old handling with use of special
signature similar to inlineArgs introduced in 1edd031
.
Endpoint modules are placed in a separate 'registry' and use
different initialization callback signature for simplicity. This makes
them inaccessible for other modules, though they are not supposed to be
anyway.
Endpoint modules are initialized before other modules. This allows
detecting unused configuration blocks by checking for modules
that were not lazily initalized after endpoint initialization.
This relies on endpoint modules being essentially "roots" of
instances dependency tree.
Idea of "semantical module names" is completely dropped now and so
HACKING.md is updated to not mention it.
This commit is contained in:
parent
97b370191d
commit
ad13d026ec
11 changed files with 190 additions and 118 deletions
69
maddy.go
69
maddy.go
|
@ -5,7 +5,6 @@ import (
|
|||
|
||||
"github.com/foxcpp/maddy/config"
|
||||
"github.com/foxcpp/maddy/log"
|
||||
"github.com/foxcpp/maddy/module"
|
||||
|
||||
// Import packages for side-effect of module registration.
|
||||
_ "github.com/foxcpp/maddy/auth/external"
|
||||
|
@ -22,13 +21,7 @@ import (
|
|||
_ "github.com/foxcpp/maddy/target/smtp_downstream"
|
||||
)
|
||||
|
||||
type modInfo struct {
|
||||
instance module.Module
|
||||
cfg config.Node
|
||||
}
|
||||
|
||||
func Start(cfg []config.Node) error {
|
||||
instances := make(map[string]modInfo)
|
||||
globals := config.NewMap(nil, &config.Node{Children: cfg})
|
||||
globals.String("hostname", false, false, "", nil)
|
||||
globals.String("autogenerated_msg_domain", false, false, "", nil)
|
||||
|
@ -45,65 +38,17 @@ func Start(cfg []config.Node) error {
|
|||
|
||||
defer log.DefaultLogger.Out.Close()
|
||||
|
||||
for _, block := range unmatched {
|
||||
var instName string
|
||||
var modAliases []string
|
||||
if len(block.Args) == 0 {
|
||||
instName = block.Name
|
||||
} else {
|
||||
instName = block.Args[0]
|
||||
modAliases = block.Args[1:]
|
||||
}
|
||||
|
||||
modName := block.Name
|
||||
|
||||
factory := module.Get(modName)
|
||||
if factory == nil {
|
||||
return config.NodeErr(&block, "unknown module: %s", modName)
|
||||
}
|
||||
|
||||
if module.HasInstance(instName) {
|
||||
return config.NodeErr(&block, "config block named %s already exists", instName)
|
||||
}
|
||||
|
||||
log.Debugln("module create", modName, instName)
|
||||
inst, err := factory(modName, instName, modAliases, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
block := block
|
||||
module.RegisterInstance(inst, config.NewMap(globals.Values, &block))
|
||||
for _, alias := range modAliases {
|
||||
if module.HasInstance(alias) {
|
||||
return config.NodeErr(&block, "config block named %s already exists", alias)
|
||||
}
|
||||
module.RegisterAlias(alias, instName)
|
||||
log.Debugln("module alias", alias, "->", instName)
|
||||
}
|
||||
instances[instName] = modInfo{instance: inst, cfg: block}
|
||||
insts, err := instancesFromConfig(globals.Values, unmatched)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, inst := range instances {
|
||||
if module.Initialized[inst.instance.InstanceName()] {
|
||||
log.Debugln("module init", inst.instance.Name(), inst.instance.InstanceName(), "skipped because it was lazily initialized before")
|
||||
continue
|
||||
}
|
||||
handleSignals()
|
||||
|
||||
module.Initialized[inst.instance.InstanceName()] = true
|
||||
log.Debugln("module init", inst.instance.Name(), inst.instance.InstanceName())
|
||||
if err := inst.instance.Init(config.NewMap(globals.Values, &inst.cfg)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
waitForSignal()
|
||||
|
||||
for _, inst := range instances {
|
||||
if closer, ok := inst.instance.(io.Closer); ok {
|
||||
log.Debugln("clean-up for module", inst.instance.Name(), inst.instance.InstanceName())
|
||||
for _, inst := range insts {
|
||||
if closer, ok := inst.(io.Closer); ok {
|
||||
if err := closer.Close(); err != nil {
|
||||
log.Printf("module %s (%s) close failed: %v", inst.instance.Name(), inst.instance.InstanceName(), err)
|
||||
log.Printf("module %s (%s) close failed: %v", inst.Name(), inst.InstanceName(), err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue