扩展 StoryBoard:事件工作器插件¶
概述¶
有时需要一种响应 StoryBoard API 事件的方法。这可以通过事件工作器插件来实现,这些插件会在 API 上发生 POST、PUT 或 DELETE 操作时收到通知。插件然后可以决定如何异步处理每个事件,从而不影响 API 的稳定性。
您的工作器将在 storyboard-worker-daemon 启动时被检测到,并创建多个工作器进程。当守护进程在 Rabbit 队列中找到消息时,它会将消息传递给每个已找到的工作器插件的 handle() 函数。
注意:为了使事件工作器插件工作,您的 StoryBoard 配置文件需要包含 enable_notifications = True。
事件工作器插件快速入门¶
步骤 1:使用 setuptools 创建一个新的 Python 项目¶
这留作练习给读者。不要忘记将 storyboard 作为依赖项包含进去。
步骤 2:实现您的插件¶
在您的插件的 setup.cfg 中添加一个注册的入口点。名称应合理且唯一
[entry_points]
storyboard.plugin.worker =
my-worker-plugin = my.namespace.plugin:MyEventWorker
然后,通过扩展 WorkerTaskBase 实现您的插件。您可以注册自己的配置组,请参阅 oslo.config 以获取更多详细信息。
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)