plugin

package
v0.5.9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 12, 2023 License: MPL-2.0 Imports: 3 Imported by: 9

Documentation

Overview

Package plugin provides a generic inversion of control model for making extensible Go packages, libraries, and applications. Like github.com/progrium/go-extpoints, but reflect based: doesn't require code generation, but have more overhead; provide more flexibility, but less type safety. It allows to register constructor for some plugin interface, and create new plugin instances or plugin instance factories. Main feature is flexible plugin configuration: plugin factory can accept config struct, that could be filled by passed hook. Config default values could be provided by registering default config factory. Such flexibility can be used to decode structured text (json/yaml/etc) into struct.

Type expectations. Here and bellow we mean by <someTypeName> some type expectations. [some type signature part] means that this part of type signature is optional.

Plugin type, let's label it as <plugin>, should be interface. Registered plugin constructor should be one of: <newPlugin> or <newFactory>. <newPlugin> should have type func([config <configType>]) (<pluginImpl>[, error]). <newFactory> should have type func([config <configType]) (func() (<pluginImpl>[, error])[, error]). <pluginImpl> should be assignable to <plugin>. That is, <plugin> methods should be subset <pluginImpl> methods. In other words, <pluginImpl> should be some <plugin> implementation, <plugin> or interface, that contains <plugin> methods as subset. <configType> type should be struct or struct pointer.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func FactoryPluginType

func FactoryPluginType(factoryType reflect.Type) (plugin reflect.Type, ok bool)

FactoryPluginType returns (SomeInterface, true) if factoryType looks like func() (SomeInterface[, error]) or (nil, false) otherwise.

func Lookup

func Lookup(pluginType reflect.Type) bool

Lookup is DefaultRegistry().Lookup shortcut.

func LookupFactory

func LookupFactory(factoryType reflect.Type) bool

LookupFactory is DefaultRegistry().LookupFactory shortcut.

func New

func New(pluginType reflect.Type, name string, fillConfOptional ...func(conf interface{}) error) (plugin interface{}, err error)

New is DefaultRegistry().New shortcut.

func NewFactory

func NewFactory(factoryType reflect.Type, name string, fillConfOptional ...func(conf interface{}) error) (factory interface{}, err error)

NewFactory is DefaultRegistry().NewFactory shortcut.

func PtrType

func PtrType(ptr interface{}) reflect.Type

PtrType is helper to extract plugin types. Example: plugin.PtrType((*PluginInterface)(nil)) instead of reflect.TypeOf((*PluginInterface)(nil)).Elem()

func Register

func Register(
	pluginType reflect.Type,
	name string,
	newPluginImpl interface{},
	defaultConfigOptional ...interface{},
)

Register is DefaultRegistry().Register shortcut.

Example
package main

import "github.com/yandex/pandora/core/plugin"

type Plugin interface {
	DoSmth()
}

func RegisterPlugin(name string, newPluginImpl interface{}, newDefaultConfigOptional ...interface{}) {
	var p Plugin
	plugin.Register(plugin.PtrType(&p), name, newPluginImpl, newDefaultConfigOptional...)
}

func main() {
	type Conf struct{ Smth string }
	New := func(Conf) Plugin { panic("") }
	RegisterPlugin("no-default", New)
	RegisterPlugin("default", New, func() Conf { return Conf{"example"} })
}
Output:

func SetDefaultRegistry added in v0.3.0

func SetDefaultRegistry(registry *Registry)

SetDefaultRegistry sets default Registry used for package *Registry methods like functions.

Types

type Registry

type Registry struct {
	// contains filtered or unexported fields
}

func DefaultRegistry

func DefaultRegistry() *Registry

DefaultRegistry returns default Registry used for package *Registry methods like functions.

func NewRegistry

func NewRegistry() *Registry

func (*Registry) Lookup

func (r *Registry) Lookup(pluginType reflect.Type) bool

Lookup returns true if any plugin constructor has been registered for given type.

func (*Registry) LookupFactory

func (r *Registry) LookupFactory(factoryType reflect.Type) bool

LookupFactory returns true if factoryType looks like func() (SomeInterface[, error]) and any plugin constructor has been registered for SomeInterface. That is, you may create instance of this factoryType using this registry.

func (*Registry) New

func (r *Registry) New(pluginType reflect.Type, name string, fillConfOptional ...func(conf interface{}) error) (plugin interface{}, err error)

New creates plugin using registered plugin constructor. Returns error if creation failed or no plugin were registered for given type and name. Passed fillConf called on created config before calling plugin factory. fillConf argument is always valid struct pointer, even if plugin factory receives no config: fillConf is called on empty struct pointer in such case. fillConf error fails plugin creation. New is thread safe, if there is no concurrent Register calls.

func (*Registry) NewFactory

func (r *Registry) NewFactory(factoryType reflect.Type, name string, fillConfOptional ...func(conf interface{}) error) (factory interface{}, err error)

NewFactory behaves like New, but creates factory func() (PluginInterface[, error]), that on call creates New plugin by registered factory. If registered constructor is <newPlugin> config is created filled for every factory call, if <newFactory, that only once for factory creation.

func (*Registry) Register

func (r *Registry) Register(
	pluginType reflect.Type,
	name string,
	constructor interface{},
	defaultConfigOptional ...interface{},
)

Register registers plugin constructor and optional default config factory, for given plugin interface type and plugin name. See package doc for type expectations details. Register designed to be called in package init func, so it panics if something go wrong. Panics if type expectations are violated. Panics if some constructor have been already registered for this (pluginType, name) pair. Register is thread unsafe.

If constructor receive config argument, default config factory can be registered. Default config factory type should be: is func() <configType>. Default config factory is optional. If no default config factory has been registered, than plugin factory will receive zero config (zero struct or pointer to zero struct). Registered constructor will never receive nil config, even there are no registered default config factory, or default config is nil. Config will be pointer to zero config in such case.

Directories

Path Synopsis
Package pluginconfig contains integration plugin with config packages.
Package pluginconfig contains integration plugin with config packages.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL