Documentation ¶
Overview ¶
The plugin package exposes functions and helpers for communicating to plugins which are implemented as standalone binary applications.
plugin.Client fully manages the lifecycle of executing the application, connecting to it, and returning the RPC client and service names for connecting to it using the otto/rpc package.
plugin.Serve fully manages listeners to expose an RPC server from a binary that plugin.Client can connect to.
Index ¶
Constants ¶
const APIVersion = "1"
The APIVersion is outputted along with the RPC address. The plugin client validates this API version and will show an error if it doesn't know how to speak it.
const MagicCookieKey = "OTTO_PLUGIN_MAGIC_COOKIE"
The "magic cookie" is used to verify that the user intended to actually run this binary. If this cookie isn't present as an environmental variable, then we bail out early with an error.
const MagicCookieValue = "11aab7ff21cb9ff7b0e9975d53f17a8dab571eac9b5ff0191730046698f07b7f"
Variables ¶
var Killed = false
If this is true, then the "unexpected EOF" panic will not be raised throughout the clients.
Functions ¶
func CleanupClients ¶
func CleanupClients()
This makes sure all the managed subprocesses are killed and properly logged. This should be called before the parent process running the plugins exits.
This must only be called _once_.
func Discover ¶
Discover discovers plugins that are in a given directory.
The directory doesn't need to be absolute. For example, "." will work fine.
This currently assumes any file matching the glob is a plugin. In the future this may be smarter about checking that a file is executable and so on.
TODO: test
func Serve ¶
func Serve(opts *ServeOpts)
Serve serves the plugins given by ServeOpts.
Serve doesn't return until the plugin is done being executed. Any errors will be outputted to the log.
func ServeMux ¶
func ServeMux(m ServeMuxMap)
ServeMux is like Serve, but serves multiple types of plugins determined by the argument given on the command-line.
This command doesn't return until the plugin is done being executed. Any errors are logged or output to stderr.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client handles the lifecycle of a plugin application, determining its RPC address, and returning various types of interface implementations across the multi-process communication layer.
func NewClient ¶
func NewClient(config *ClientConfig) (c *Client)
Creates a new plugin client which manages the lifecycle of an external plugin and gets the address for the RPC connection.
The client must be cleaned up at some point by calling Kill(). If the client is a managed client (created with NewManagedClient) you can just call CleanupClients at the end of your program and they will be properly cleaned.
func (*Client) Client ¶
Client returns an RPC client for the plugin.
Subsequent calls to this will return the same RPC client.
func (*Client) Kill ¶
func (c *Client) Kill()
End the executing subprocess (if it is running) and perform any cleanup tasks necessary such as capturing any remaining logs and so on.
This method blocks until the process successfully exits.
This method can safely be called multiple times.
func (*Client) Start ¶
Starts the underlying subprocess, communicating with it to negotiate a port for RPC connections, and returning the address to connect via RPC.
This method is safe to call multiple times. Subsequent calls have no effect. Once a client has been started once, it cannot be started again, even if it was killed.
type ClientConfig ¶
type ClientConfig struct { // The unstarted subprocess for starting the plugin. Cmd *exec.Cmd // Managed represents if the client should be managed by the // plugin package or not. If true, then by calling CleanupClients, // it will automatically be cleaned up. Otherwise, the client // user is fully responsible for making sure to Kill all plugin // clients. By default the client is _not_ managed. Managed bool // The minimum and maximum port to use for communicating with // the subprocess. If not set, this defaults to 10,000 and 25,000 // respectively. MinPort, MaxPort uint // StartTimeout is the timeout to wait for the plugin to say it // has started successfully. StartTimeout time.Duration // If non-nil, then the stderr of the client will be written to here // (as well as the log). This is the original os.Stderr of the subprocess. // This isn't the output of synced stderr. Stderr io.Writer // SyncStdout, SyncStderr can be set to override the // respective os.Std* values in the plugin. Care should be taken to // avoid races here. If these are nil, then this will automatically be // hooked up to os.Stdin, Stdout, and Stderr, respectively. // // If the default values (nil) are used, then this package will not // sync any of these streams. SyncStdout io.Writer SyncStderr io.Writer }
ClientConfig is the configuration used to initialize a new plugin client. After being used to initialize a plugin client, that configuration must not be modified again.
type ServeMuxMap ¶
ServeMuxMap is the type that is used to configure ServeMux