pluginfx

package module
v0.0.0 Latest Latest
Warning

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

Go to latest
Published: Nov 3, 2021 License: Apache-2.0 Imports: 8 Imported by: 0

README

pluginfx

pluginfx does something good.

Build Status codecov.io Go Report Card Apache V2 License Quality Gate Status GitHub release PkgGoDev

Setup

  1. Search and replace pluginfx with your project name.
  2. Initialize go.mod file: go mod init github.com/xmidt-org/pluginfx
  3. Add org teams to project (Settings > Manage Access):
    • xmidt-org/admins with Admin role
    • xmidt-org/server-writers with Write role
  4. Manually create the first release. After v0.0.1 exists, other releases will be made by automation after the CHANGELOG is updated to reflect a new version header and nothing under the Unreleased header.
  5. For libraries:
    1. Add org workflows in dir .github/workflows: push, tag, and release. This can be done by going to the Actions tab for the repo on the github site.
    2. Remove the following files/dirs: .dockerignore, Dockerfile, Makefile, rpkg.macros, pluginfx.yaml, deploy/, and conf/.
  6. For applications:
    1. Remove PkgGoDev badge from this file.
    2. Add org workflows in dir .github/workflows: push, tag, release, and docker-release. This can be done by going to the Actions tab for the repo on the github site.
    3. Add project name, .ignore, and errors.txt to .gitignore file.
    4. Update Dockerfile - choose new ports to expose that no current XMiDT application is using.
    5. Update deploy/packaging/pluginfx.spec file to have a proper Summary and Description.
    6. Update conf/pluginfx.service file to have a proper Description.

Summary

Summary should be a small paragraph explanation of what this project does.

Table of Contents

Code of Conduct

This project and everyone participating in it are governed by the XMiDT Code Of Conduct. By participating, you agree to this Code.

Details

Add details here.

Install

Add details here.

Contributing

Refer to CONTRIBUTING.md.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsMissingSymbolError

func IsMissingSymbolError(err error) bool

IsMissingSymbolError tests err to see if it is a *MissingSymbolError. This function is a shorthand for situations where calling code only needs to be aware that an error indicated a symbol was missing.

func Lookup

func Lookup(p Plugin, name string) (interface{}, error)

Lookup invokes s.Lookup and normalizes any error to *MissingSymbolError.

Types

type Annotated

type Annotated struct {
	// Name is the optional name of the component emitted by the Constructor.lue
	// Either Name or Group must be set, or an error is raised.
	Name string

	// Group is the value group for the component emitted by the Constructor.
	// Either Name or Group must be set, or an error is raised.
	Group string

	// Target is the name of a function symbol that must be legal to
	// use with fx.Annotated.Target.
	Target string
}

Annotated is an analog of fx.Annotated for plugin symbols. This type gives more control over how a plugin constructor gets placed into the enclosing fx.App.

type InvalidLifecycleError

type InvalidLifecycleError struct {
	Name string
	Type reflect.Type
}

InvalidLifecycleError indicates that a symbol was not usable as an uber/fx lifecycle callback via fx.Hook.

func (*InvalidLifecycleError) Error

func (ile *InvalidLifecycleError) Error() string

type InvalidTargetError

type InvalidTargetError struct {
	Name string
	Type reflect.Type
}

InvalidTargetError indicates that a type was not valid for the fx.Annotated.Target field. This is more restrictive than a constructor. Targets must return exactly (1) non-error object, with an optional error.

func (*InvalidTargetError) Error

func (ite *InvalidTargetError) Error() string

type Lifecycle

type Lifecycle struct {
	// OnStart is the optional symbol name of a function that can be invoked on application startup.
	//
	// This field must refer to an exported function in the plugin that has any of the following
	// signatures:
	//
	//   - func()
	//   - func() error
	//   - func(context.Context)
	//   - func(context.Context) error
	//
	// A function with any of those signatures will be registered as an fx.Hook and will run
	// on application startup.  Any other signature or non-function type will shortcircuit
	// the application with an error.
	OnStart string

	// OnStop is the optional symbol name of a function that can be invoked on application shutdown.
	// The symbol referred to by this field may have any of the same function signatures as OnStart.
	OnStop string

	// IgnoreMissing defines what happens when either OnStart or OnStop are set and not present.
	// If this field is true, a missing OnStart or OnStop is silently ignored.  If this field is false,
	// then a missing OnStart or OnStop from a plugin will shortcircuit application startup with an error.
	IgnoreMissing bool
}

Lifecycle describes how to bind a plugin to an enclosing application's lifecycle.

func (Lifecycle) Bind

func (lc Lifecycle) Bind(p Plugin) fx.Option

Bind binds the given plugin to the enclosing application's lifecycle, using the symbol information configured in OnStart and OnStop.

type MissingSymbolError

type MissingSymbolError struct {
	Name string
	Err  error
}

MissingSymbolError indicates that a symbol was not found. This error is returned by Lookup to normalize errors coming from plugins.

func (*MissingSymbolError) Error

func (mse *MissingSymbolError) Error() string

func (*MissingSymbolError) Unwrap

func (mse *MissingSymbolError) Unwrap() error

type OpenError

type OpenError struct {
	Path string
	Err  error
}

OpenError is returned by Open to indicate that a source of symbols could not be loaded.

func (*OpenError) Error

func (oe *OpenError) Error() string

func (*OpenError) Unwrap

func (oe *OpenError) Unwrap() error

type P

type P struct {
	// Name is the optional name of the plugin component within the application.  This
	// field is ignored if Anonymous is set.
	Name string

	// Group is the optional value group to place the loaded plugin into.  This field
	// is ignored if Anonymous is set.
	Group string

	// Anonymous controls whether the plugin itself is provided as a component
	// to the enclosing fx.App.  If this field is true, then the plugin is not
	// placed into the fx.App regardless of the values of Name and Group.
	Anonymous bool

	// Path is the plugin's path.  This field is required.  Variables are expanded
	// via os.ExpandEnv.
	Path string

	// Symbols describes the optional set of functions exported by the plugin to be
	// bound to the enclosing fx.App.  Both provide and invoke functions can be defined
	// using this field.
	Symbols Symbols

	// Lifecycle is the optional binding from a plugin's symbols to the enclosing
	// application.
	Lifecycle Lifecycle
}

P describes how to load a single plugin and integrate it into an enclosing fx.App.

func (P) Provide

func (p P) Provide() fx.Option

Provide builds the appropriate options to integrate this plugin into an enclosing fx.App.

Typical usage:

app := fx.New(
  pluginx.P{
    Anonymous: true, // leave unset if you want the plugin accessible via DI
    Path: "/etc/lib/something.so",
    Symbols: pluginfx.Symbols {
      Names: []interface{}{
        "MyConstructor",
      },
    },
    Lifecycle: pluginfx.Lifecycle {
      OnStart: "Initialize",
    },
  }.Provide()
)

type Plugin

type Plugin interface {
	// Lookup returns the value of the given symbol, or an error
	// if no such symbol exists.
	//
	// The *plugin.Plugin type returns a generated error from this method,
	// making error disambiguation hard or impossible.  The Lookup function
	// in this package helps with that by ensuring that a *MissingSymbolError
	// is returned in cases where a symbol cannot be found.
	Lookup(string) (plugin.Symbol, error)
}

Plugin defines the behavior of something that can look up exported symbols. *plugin.Plugin implements this interface.

func Open

func Open(path string) (Plugin, error)

Open loads a Plugin from a path. This is the analog to plugin.Open, and returns a *OpenError instead of a generated error.

type S

type S struct {
	// Group is the optional value group to place each plugin in this set into.  If this
	// field is unset, the loaded plugins are not added as components.
	Group string

	// Paths are the plugin paths to load.  Each of these paths may be a filesystem glob,
	// in which case all matching files are loaded as plugins.  Variable expansion is also
	// done on each element via os.ExpandEnv.
	Paths []string

	// Symbols are the symbols to be loaded from each loaded plugin.
	Symbols Symbols

	// Lifecycle describes the symbols from each loaded plugin to be bound to the
	// enclosing application.
	Lifecycle Lifecycle
}

S describes how to load multiple plugins as a bundle and integrate each of them into an enclosing fx.App.

func (S) Provide

func (s S) Provide() fx.Option

Provide opens a list of plugins described in the Paths field. These plugins are optionally put into a value group if the Group field is set. Each plugin is then examined for symbols to provide to the enclosing fx.App in a manner similar to Plugin.Provide.

type SymbolMap

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

SymbolMap is a map implementation of Symbols. It allows for an in-memory implementation of a plugin for testing or for production defaults.

The zero value of this type is a usable, empty "plugin". An existing map may be copied into a new *SymbolMap by using NewSymbolMap.

func NewSymbolMap

func NewSymbolMap(m map[string]interface{}) *SymbolMap

NewSymbolMap shallow copies the contents of a map onto a new SymbolMap instance. Each symbol value is handled with Set.

func NewSymbols

func NewSymbols(namesAndValues ...interface{}) *SymbolMap

NewSymbols is like NewSymbolMap, but it uses a sequence of name/value pairs. This function is often easier to use than NewSymbolMap, due to the noisiness of declaring a map.

This function panics if namesAndValues is not empty and does not have an even number of elements. It also panics if any even-numbered element (including zero) is not a string.

func (*SymbolMap) Del

func (sm *SymbolMap) Del(name string)

Del removes a symbol from this map.

func (*SymbolMap) Lookup

func (sm *SymbolMap) Lookup(name string) (plugin.Symbol, error)

Lookup implements the Symbols interface.

func (*SymbolMap) Set

func (sm *SymbolMap) Set(name string, value interface{})

Set adds a symbol to this map. The value may not be a nil pointer, or this method panics.

If value is a function or a non-nil pointer, it is added to this map as is. Otherwise, a pointer is created that points to value, and that pointer is added to this map.

type Symbols

type Symbols struct {
	// Names are the symbol names to load into the enclosing fx.App.  Each
	// element of this slice must be either a string or an Annotated.
	//
	// Each symbol must refer to a function, or an error is raised.
	//
	// If an element is a string, it may be either a constructor or an invoke function.
	// If the function returns nothing or an error, it is wrapped in fx.Invoke.  Otherwise,
	// it is passed to fx.Provide.
	//
	// If an element is an Annotated, then the Target field is used to load a constructor.
	// This target constructor must return exactly (1) non-error value along with an optional
	// error.
	Names []interface{}

	// IgnoreMissing controls what happens when a symbol is not found in a plugin.
	// If this field is true, then missing symbols are silently ignored.  Otherwise,
	// a missing symbol will shortcircuit application startup with an error.
	IgnoreMissing bool
}

Symbols describes how to bootstrap a set of symbols within an enclosing fx.App.

func (Symbols) Load

func (s Symbols) Load(p Plugin) fx.Option

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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