Convert plugin API to be purely event based
See original GitHub issueWhat things currently look like.
The current plugin API looks like this.
configure_parser
: Hook that can be implemented by plugin to modify CLI parser configurationshould_start
: Called byPluginManager
to check whether a plugin should be started based on an eventstart
: Called by thePluginManager
ifshould_start
returnsTrue
and the plugin has not been started yet.stop
: Called by thePluginManager
to stop plugins during shutdown.
The Event API works through the PluginManager
and all events are fired by the PluginManager
. The following events are currenty available.
TrinityStartupEvent
- broadcast when theNodeClass
is launched/startedPluginStartedEvent
- broadcast when a specific plugin is startedResourceAvaiableEvent
- broadcast when a resource becomes available
This API has been a good start, but it has been built in direct response to the needs presented by the transaction pool and the other initial plugin experiments. Now that we are starting to see what a plugin might look like, I propose the following changes to this API.
What I think things should look like
First, I want to better define the initialization process and plugin lifecycle.
Plugin.bootstrap(arg_parser, sub_parser)
:- The very thing that is called on a plugin. Lets experiment with making this a
classmethod
since this will occur early enough in the process that I don’t think we can realistically initialize plugins at this stage. - This is where plugins get the chance to modify the CLI
- The very thing that is called on a plugin. Lets experiment with making this a
Plugin.__init__(args, token)
:- Plugin classes get initialized.
args
is the CLIArgparser
result.token
is aCancelToken
that the plugin should use to gracefully handle shutdowns (not fully fleshed out).
Plugin.ready(chain_config, broadcast_queue, subscription_queue)
- Concept lifted from django AppConfig.ready
- Name subject to change
- Concept is that this is the last point prior to things starting
broadcast_queue
is anasyncio.Queue
that the plugin can use to broadcast an event (more below)subscription_queue
is anasyncio.Queue
that the plugin can consume events that have been broadcast by other plugins. (more below)
Plugin.run()
- Starts the plugin
Plugin.cancel()
- Called when the app is exiting. Last chance for a plugin to gracefully shutdown.
After ready
and before shutdown
is when the app is running. Within these boundaries, the Trinity application is running and plugins are active. During this period, plugins interact via events.
Here is the best description of how I think events should work.
- Events should probably be registered sometime during initialization. This could happen automatically by the
PluginManager
.
Plugin.get_broadcast_events()
: Returns all of the events that this plugin can broadcast.Plugin.get_subscription_events(registry):
Returns all of the events that this plugin wants to subscribe to. Theregistry
would be a data structure containing all of the registered events (and probably the plugin which registered them).
- Plugins may broadcast any event that it registered from
get_broadcast_events
using thebroadcast_queue
- Plugins read events from the
subscription_queue
and respond.
We probably have a few core events that are provided by the plugin manager or some other built-in plugin.
DiscoveryStarted
to give plugins access to theDiscoveryService
PeerPoolStarted
to give plugins access to thePeerPool
Issue Analytics
- State:
- Created 5 years ago
- Comments:7 (7 by maintainers)
I think with the event bus proving more and more as a viable solution, and if we don’t hit a big performance problem, then, I think we should retire the plugin event mechanism entirely and simply let all event based communication go through the event bus.
We achieved this by basing our plugin architecture on the event bus.