plugins

package module
v0.0.0-...-9156858 Latest Latest
Warning

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

Go to latest
Published: Apr 8, 2015 License: MIT Imports: 12 Imported by: 0

README

Plugins

This is a implementation of a "plugin" system for Go. Go does not have dynamic loading so it is not a true plugin system, but rather a way to handle inter-process communication with intention to augment a main system.

Plugins can be connected in multiple ways. They are defined as a interface, so as long as that is implemented, you can hook one up in what ever way you want, but the default implementation is RemotePlugin that defines a way to connect to a another process over any Reader and Writer with some protocol negotiations of format (gob, json and xml supported out-of-the-box).

This means that together with a convenience function to run all binaries from a folder, it is easy to set up a plugin api for your program.

  1. Create a PluginHandler
  2. Setup some events that you subscribe to.
  3. Load all the plugins in the folder.
  4. ???
  5. Profit!

When ever something happens in your application, notify all interested plugins by using the PluginHandler.Dispatch(Event, Args) method

Protocol

The protocol is divided into two stages. The first stage is a two-way handshake where the plugin/client starts.

Client --{ PluginDeclaration }-> Server
Client <-{  FormatResponse   }-- Server

where PluginDeclaration is a JSON-encoded object with the following fields:

name       string
subscribes [Event]
provides   [Event]
formats    [Format]

[Type] means a list of <Type>
Event is a string representing a event, as dot-separated nodes in a tree
	Ex: "job.complete"
		"tracker.calibration.start"

Format is a string representation of a MIME type as defined in RFC 2046.
	Ex: "application/json"
		"application/xml"
		"application/gob"

and FormatDeclaration is a JSON encoded object with these fields:

format Format
error Error

where Format is as defined above and Error is a integer error-code as defined in the Errors section below.

The second stage is the communication stage, using the format negotiated in the handshake stage.

This stage use packets on the form

Event
Args

in that order (if important for the format chosen). Event is as described above Args is a mapping from string to any type. In JSON, this would be a simple object. In Gob, it would be a map[string]interface{}

These packets can be sent at any time by any side. Both sides are to listen for incomming packets at all times and handle them in a timely fashion.

This stage continues until either side closes the communications channel.

Errors

Transmission Errors
0: Success
1: No common format found during negotiations.
Server Errors

*To be written

Client Errors

*To be written

Documentation

Index

Constants

This section is empty.

Variables

View Source
var SupportedFormats = map[Format]FormatFactory{

	JSON: FormatFactory{50, jsonFactory},
	XML:  FormatFactory{0, xmlFactory},
}

Functions

This section is empty.

Types

type Args

type Args map[string]interface{}

type Client

type Client struct {
	Muxer
	// contains filtered or unexported fields
}

func NewClient

func NewClient(decl PluginDecl, r io.ReadCloser, w io.WriteCloser) (c *Client, err error)

Creates a new plugin client from a declaration, a reader and the corresponding writer. The Format field of the declaration can be omitted (nil) and will in that case be set to a list of formats supported by the system (All keys in SupportedFormats).

func (*Client) Dispatch

func (c *Client) Dispatch(event Event, args Args) error

func (*Client) Run

func (c *Client) Run() (err error)

type Decoder

type Decoder interface {
	Decode(e interface{}) error
}

type Encoder

type Encoder interface {
	Encode(e interface{}) error
}

type Error

type Error int
const (
	Success Error = iota
	NoSupportedFormat
)

Transmission errors

const (
	Unblocking Error = 100 + iota
	NotImplemented
	NotDirectory
	DuplicatePlugin
)

Server errors

func (Error) Error

func (e Error) Error() string

type Event

type Event string

type Format

type Format string
var (
	JSON Format = "application/json"
	GOB  Format = "application/gob"
	XML  Format = "application/xml"
)

type FormatFactory

type FormatFactory struct {
	Weight    int
	Construct func(r io.ReadCloser, w io.WriteCloser) (Encoder, Decoder)
}

type Handler

type Handler interface {
	HandleEvent(Event, Args)
}

type HandlerFunc

type HandlerFunc func(Event, Args)

func (HandlerFunc) HandleEvent

func (hf HandlerFunc) HandleEvent(event Event, args Args)

type Manager

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

A plugin manager Manages plugins by routing events between them. Also allows a local handler to recieve the events and react to them.

func NewManager

func NewManager() *Manager

Returns a new plugin Manager ready for use. A default Muxer is installed as the handler

func (Manager) Dispatch

func (ph Manager) Dispatch(e Event, args Args) error

Introduces a new event into the handler for processing and sending to relevant plugins.

func (*Manager) Handle

func (ph *Manager) Handle(pl Plugin)

Registers a plugin to be handled by the handler. The name of the plugin must be unique

func (*Manager) HandleAll

func (ph *Manager) HandleAll(pls ...Plugin)

Convenience method Equivalent to calling Handle on all plugins individually

func (Manager) Handler

func (ph Manager) Handler() Handler

Returns the current handler used.

func (*Manager) ListenAndServe

func (ph *Manager) ListenAndServe() error

func (Manager) Muxer

func (ph Manager) Muxer() Muxer

Returns the installed handler if it is a Muxer Otherwise, returns nil

func (*Manager) SetHandler

func (ph *Manager) SetHandler(h Handler)

Sets the handler to be used.

func (*Manager) Unhandle

func (ph *Manager) Unhandle(pl Plugin)

Unhandles the plugin. The plugin will not recieve future events.

type Muxer

type Muxer interface {
	Handler
	AddHandler(Event, Handler)
	RemoveHandler(Event, Handler)
}

type Plugin

type Plugin interface {
	Name() string
	Provides() []Event
	Subscribes() []Event

	Send(Event, Args) error
	Recieve() (Event, Args, error)
}

func Load

func Load(path string) (Plugin, error)

Loads the plugins at the given path Returns a valid plugin or a non-nil error

func LoadAll

func LoadAll(path string) ([]Plugin, error)

type PluginDecl

type PluginDecl struct {
	Name       string   `json:"name"`
	Subscribes []Event  `json:"subscribes"`
	Provides   []Event  `json:"provides"`
	Formats    []Format `json:"formats"`
}

type RemotePlugin

type RemotePlugin struct {
	PluginDecl
	// contains filtered or unexported fields
}

func NewRemotePlugin

func NewRemotePlugin(r io.ReadCloser, w io.WriteCloser) (pl *RemotePlugin, err error)

func (RemotePlugin) Name

func (rp RemotePlugin) Name() string

func (RemotePlugin) Provides

func (rp RemotePlugin) Provides() []Event

func (RemotePlugin) Recieve

func (rp RemotePlugin) Recieve() (Event, Args, error)

func (RemotePlugin) Send

func (rp RemotePlugin) Send(e Event, args Args) error

func (RemotePlugin) Subscribes

func (rp RemotePlugin) Subscribes() []Event

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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