maddy

Fork https://github.com/foxcpp/maddy

git clone git://git.lin.moe/go/maddy.git

  1/*
  2Maddy Mail Server - Composable all-in-one email server.
  3Copyright © 2019-2020 Max Mazurov <fox.cpp@disroot.org>, Maddy Mail Server contributors
  4
  5This program is free software: you can redistribute it and/or modify
  6it under the terms of the GNU General Public License as published by
  7the Free Software Foundation, either version 3 of the License, or
  8(at your option) any later version.
  9
 10This program is distributed in the hope that it will be useful,
 11but WITHOUT ANY WARRANTY; without even the implied warranty of
 12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 13GNU General Public License for more details.
 14
 15You should have received a copy of the GNU General Public License
 16along with this program.  If not, see <https://www.gnu.org/licenses/>.
 17*/
 18
 19package module
 20
 21import (
 22	"sync"
 23
 24	"github.com/foxcpp/maddy/framework/log"
 25)
 26
 27var (
 28	// NoRun makes sure modules do not start any bacground tests.
 29	//
 30	// If it set - modules should not perform any actual work and should stop
 31	// once the configuration is read and verified to be correct.
 32	// TODO: Replace it with separation of Init and Run at interface level.
 33	NoRun = false
 34
 35	modules     = make(map[string]FuncNewModule)
 36	endpoints   = make(map[string]FuncNewEndpoint)
 37	modulesLock sync.RWMutex
 38)
 39
 40// Register adds module factory function to global registry.
 41//
 42// name must be unique. Register will panic if module with specified name
 43// already exists in registry.
 44//
 45// You probably want to call this function from func init() of module package.
 46func Register(name string, factory FuncNewModule) {
 47	modulesLock.Lock()
 48	defer modulesLock.Unlock()
 49
 50	if _, ok := modules[name]; ok {
 51		panic("Register: module with specified name is already registered: " + name)
 52	}
 53
 54	modules[name] = factory
 55}
 56
 57// RegisterDeprecated adds module factory function to global registry.
 58//
 59// It prints warning to the log about name being deprecated and suggests using
 60// a new name.
 61func RegisterDeprecated(name, newName string, factory FuncNewModule) {
 62	Register(name, func(modName, instName string, aliases, inlineArgs []string) (Module, error) {
 63		log.Printf("module initialized via deprecated name %s, %s should be used instead; deprecated name may be removed in the next version", name, newName)
 64		return factory(modName, instName, aliases, inlineArgs)
 65	})
 66}
 67
 68// Get returns module from global registry.
 69//
 70// This function does not return endpoint-type modules, use GetEndpoint for
 71// that.
 72// Nil is returned if no module with specified name is registered.
 73func Get(name string) FuncNewModule {
 74	modulesLock.RLock()
 75	defer modulesLock.RUnlock()
 76
 77	return modules[name]
 78}
 79
 80// GetEndpoints returns an endpoint module from global registry.
 81//
 82// Nil is returned if no module with specified name is registered.
 83func GetEndpoint(name string) FuncNewEndpoint {
 84	modulesLock.RLock()
 85	defer modulesLock.RUnlock()
 86
 87	return endpoints[name]
 88}
 89
 90// RegisterEndpoint registers an endpoint module.
 91//
 92// See FuncNewEndpoint for information about
 93// differences of endpoint modules from regular modules.
 94func RegisterEndpoint(name string, factory FuncNewEndpoint) {
 95	modulesLock.Lock()
 96	defer modulesLock.Unlock()
 97
 98	if _, ok := endpoints[name]; ok {
 99		panic("Register: module with specified name is already registered: " + name)
100	}
101
102	endpoints[name] = factory
103}