This commit adds a section to the documentation which briefly explains how to go about creating an event worker plugin, for reacting to POST, PUT, and DELETE requests to the API. Change-Id: If76124d1a6e0857a5ebe765755b0cc60ccba37bd
4.0 KiB
Extending StoryBoard: Event Worker Plugins
Overview
It is sometimes useful to have a method to react to StoryBoard's API events. This can be done using Event Worker plugins, which recieve a notification whenever a POST, PUT, or DELETE action occurs on the API. The plugin can then decide how to process each event asynchronously so as not to impact the stability of the API.
Your workers will be detected by storyboard-worker-daemon when it starts, and a number of worker processes will be created. When a daemon finds a message in the Rabbit queue, it passes the message to the handle() function of each worker plugin it has found.
Note: In order for event worker plugins to work, your StoryBoard config file will need to contain enable_notifications = True.
Event Worker Plugin Quickstart
Step 1: Create a new python project using setuptools
This is left as an exercise to the reader. Don't forget to include storyboard as a requirement.
Step 2: Implement your plugin
Add a registered entry point in your plugin's setup.cfg. The name should be reasonably unique:
[entry_points]
storyboard.plugin.worker =
my-worker-plugin = my.namespace.plugin:MyEventWorker
Then, implement your plugin by extending WorkerTaskBase. You may register your own configuration groups, please see oslo.config for more details.:
from storyboard.plugin.event_worker import WorkerTaskBase
class MyEventWorker(WorkerTaskBase):
def enabled(self):
'''This method should return whether the plugin is enabled and
configured. It has access to self.config, which is a reference to
storyboard's global configuration object.
'''
return True
def handle(self, session, author, method, path, status, resource,
resource_id, sub_resource=None, sub_resource_id=None,
resource_before=None, resource_after=None):
"""This method takes information about an API event and does
something with it, for example creating a SubscriptionEvent
in the database for everyone subscribed to the affected resource.
:param session: An event-specific SQLAlchemy session.
:param author: The author's user record.
:param method: The HTTP Method.
:param path: The full HTTP Path requested.
:param status: The returned HTTP Status of the response.
:param resource: The resource type.
:param resource_id: The ID of the resource.
:param sub_resource: The subresource type.
:param sub_resource_id: The ID of the subresource.
:param resource_before: The resource state before this event occurred.
:param resource_after: The resource state after this event occurred.
"""
if resource == 'timeline_event':
event = db_api.entity_get(models.TimeLineEvent, resource_id,
session=session)
subscribers = sub_api.subscription_get_all_subscriber_ids(
'story', event.story_id, session=session)
for user_id in subscribers:
event_info = event.event_info
db_api.entity_create(models.SubscriptionEvents, {
"author_id": author.id,
"subscriber_id": user_id,
"event_type": event.event_type,
"event_info": event_info
}, session=session)
Step 3: Install your plugin
Finally, install your plugin, which may require you switch into storyboard's virtual environment. Pip should automatically register your plugin:
pip install my-storyboard-plugin