mirror of https://github.com/caddyserver/caddy.git
Improve godoc for contexts
This commit is contained in:
parent
1f0c061ce3
commit
1a20fe330e
39
context.go
39
context.go
|
@ -10,12 +10,30 @@ import (
|
|||
"github.com/mholt/certmagic"
|
||||
)
|
||||
|
||||
// Context is a type which defines the lifetime of modules that
|
||||
// are loaded and provides access to the parent configuration
|
||||
// that spawned the modules which are loaded. It should be used
|
||||
// with care and only wrapped with derivation functions from
|
||||
// the standard context package if you don't need the Caddy
|
||||
// specific features. These contexts are cancelled when the
|
||||
// lifetime of the modules loaded from it are over.
|
||||
//
|
||||
// Use NewContext() to get a valid value (but most modules will
|
||||
// not actually need to do this).
|
||||
type Context struct {
|
||||
context.Context
|
||||
moduleInstances map[string][]interface{}
|
||||
cfg *Config
|
||||
}
|
||||
|
||||
// NewContext provides a new context derived from the given
|
||||
// context ctx. Normally, you will not need to call this
|
||||
// function unless you are loading modules which have a
|
||||
// different lifespan than the ones for the context the
|
||||
// module was provisioned with. Be sure to call the cancel
|
||||
// func when the context is to be cleaned up so that
|
||||
// modules which are loaded will be properly unloaded.
|
||||
// See standard library context package's documentation.
|
||||
func NewContext(ctx Context) (Context, context.CancelFunc) {
|
||||
newCtx := Context{moduleInstances: make(map[string][]interface{}), cfg: ctx.cfg}
|
||||
c, cancel := context.WithCancel(ctx.Context)
|
||||
|
@ -36,6 +54,14 @@ func NewContext(ctx Context) (Context, context.CancelFunc) {
|
|||
return newCtx, wrappedCancel
|
||||
}
|
||||
|
||||
// LoadModule decodes rawMsg into a new instance of mod and
|
||||
// returns the value. If mod.New() does not return a pointer
|
||||
// value, it is converted to one so that it is unmarshaled
|
||||
// into the underlying concrete type. If mod.New is nil, an
|
||||
// error is returned. If the module implements Validator or
|
||||
// Provisioner interfaces, those methods are invoked to
|
||||
// ensure the module is fully configured and valid before
|
||||
// being used.
|
||||
func (ctx Context) LoadModule(name string, rawMsg json.RawMessage) (interface{}, error) {
|
||||
modulesMu.Lock()
|
||||
mod, ok := modules[name]
|
||||
|
@ -74,7 +100,7 @@ func (ctx Context) LoadModule(name string, rawMsg json.RawMessage) (interface{},
|
|||
}
|
||||
|
||||
if validator, ok := val.(Validator); ok {
|
||||
err := validator.Validate(ctx)
|
||||
err := validator.Validate()
|
||||
if err != nil {
|
||||
if cleanerUpper, ok := val.(CleanerUpper); ok {
|
||||
err2 := cleanerUpper.Cleanup()
|
||||
|
@ -91,6 +117,17 @@ func (ctx Context) LoadModule(name string, rawMsg json.RawMessage) (interface{},
|
|||
return val, nil
|
||||
}
|
||||
|
||||
// LoadModuleInline loads a module from a JSON raw message which decodes
|
||||
// to a map[string]interface{}, where one of the keys is moduleNameKey
|
||||
// and the corresponding value is the module name as a string, which
|
||||
// can be found in the given scope.
|
||||
//
|
||||
// This allows modules to be decoded into their concrete types and
|
||||
// used when their names cannot be the unique key in a map, such as
|
||||
// when there are multiple instances in the map or it appears in an
|
||||
// array (where there are no custom keys). In other words, the key
|
||||
// containing the module name is treated special/separate from all
|
||||
// the other keys.
|
||||
func (ctx Context) LoadModuleInline(moduleNameKey, moduleScope string, raw json.RawMessage) (interface{}, error) {
|
||||
moduleName, err := getModuleNameInline(moduleNameKey, raw)
|
||||
if err != nil {
|
||||
|
|
31
modules.go
31
modules.go
|
@ -136,23 +136,32 @@ func getModuleNameInline(moduleNameKey string, raw json.RawMessage) (string, err
|
|||
return moduleName, nil
|
||||
}
|
||||
|
||||
// Validator is implemented by modules which can verify that their
|
||||
// configurations are valid. This method will be called after New()
|
||||
// instantiations of modules (if implemented). Validation should
|
||||
// always be fast (imperceptible running time) and an error should
|
||||
// be returned only if the value's configuration is invalid.
|
||||
type Validator interface {
|
||||
Validate(Context) error
|
||||
}
|
||||
|
||||
// Provisioner is implemented by modules which may need to perform
|
||||
// some additional "setup" steps immediately after being loaded.
|
||||
// This method will be called after Validate() (if implemented).
|
||||
// Provisioning should be fast (imperceptible running time). If
|
||||
// any side-effects result in the execution of this function (e.g.
|
||||
// creating global state, any other allocations which require
|
||||
// garbage collection, opening files, starting goroutines etc.),
|
||||
// be sure to clean up properly by implementing the CleanerUpper
|
||||
// interface to avoid leaking resources.
|
||||
type Provisioner interface {
|
||||
Provision(Context) error
|
||||
}
|
||||
|
||||
// TODO: different name...
|
||||
// Validator is implemented by modules which can verify that their
|
||||
// configurations are valid. This method will be called after
|
||||
// Provision() (if implemented). Validation should always be fast
|
||||
// (imperceptible running time) and an error should be returned only
|
||||
// if the value's configuration is invalid.
|
||||
type Validator interface {
|
||||
Validate() error
|
||||
}
|
||||
|
||||
// CleanerUpper is implemented by modules which may have side-effects
|
||||
// such as opened files, spawned goroutines, or allocated some sort
|
||||
// of non-local state when they were provisioned. This method should
|
||||
// deallocate/cleanup those resources to prevent memory leaks. Cleanup
|
||||
// should be fast and efficient.
|
||||
type CleanerUpper interface {
|
||||
Cleanup() error
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue