socloz/event-queue-bundle

一个允许异步执行事件监听器的Symfony2扩展包。

dev-master 2014-12-30 09:49 UTC

This package is not auto-updated.

Last update: 2024-09-22 03:12:23 UTC


README

一个允许异步执行事件监听器的Symfony2扩展包。

只要满足某些条件,应用程序使用该扩展包无需进行代码更改。

该扩展包由两部分组成:监听器和工作者。

监听器

  • 以最高优先级注册配置的事件,
  • 阻止事件的传播,
  • 将序列化的事件发送到队列。

工作者

  • 为配置的事件构建应用程序监听器的列表,
  • 监听队列并反序列化接收的事件,
  • 执行监听器。

依赖项

  • beanstalk - 可以添加其他队列

设置

$loader->registerPrefixes(array(
    [...]
    'Socket_'          => __DIR__.'/../vendor/beanstalk/src',
));
  • 配置服务
socloz_event_queue:
    queue_type: beanstalkd
    forward: [ my.event.name, my.event.name ]
    serialize: mongoodm
    beanstalkd:
        host: 127.0.0.1
        tube: event_queue

其他可能的配置选项(默认值)

socloz_event_queue:
    beanstalkd:
        port: 11300
        persistent: true
        timeout: 1
  • 启动工作者(推荐使用进程管理守护进程,如 supervisord)
$ app/console socloz:event_queue:worker [stop_after]

如果使用,stop_after 允许工作者在经过一定秒数后停止(警告:测试是在任务执行之后进行的)。

序列化器

在发送之前需要将事件进行序列化。来自 ORM/ODM 的对象通常无法使用 PHP 内置类进行序列化和反序列化,因此该扩展包使用专用序列化器。

目前有 2 个基本序列化器存在

  • Mandango (serialize: mandango),
  • MongoDB ODM (serialize: mongoodm)。

它们假设

  • ORM/ODM 对象存在 getId 方法,
  • 所有具有 getId 方法的对象都来自 ORM/ODM,
  • 在派发事件之前对象已被保存(远程监听器从数据库中实例化对象),
  • 可以使用构造函数创建事件而不调用其他方法,
  • 构造函数参数与类属性名称相同。

我没有时间/无法找到解决方案。请随时贡献更好的序列化器!

ReflectionClass::newInstanceWithoutConstructor 将有所帮助,但它仅在 5.4 版本中添加,如果在启动时构建类特定的序列化器,也可以提高性能,如果您需要转发大量事件。

示例事件类

<?php

namespace Socloz\APIBundle\Event\Event;

use Symfony\Component\EventDispatcher\Event;

class CategoryDeleteEvent extends Event
{
    protected $category;

    public function __construct($category)
    {
        $this->category = $category;
    }

    public function getCategory()
    {
        return $this->category;
    }
}

如果您需要序列化器,它需要实现 Socloz\EventQueueBundle\Serialize\SerializeInterface 接口。

interface SerializeInterface
{
    public function serialize($event);

    public function deserialize($data);
}

然后需要将其注册为名为 socloz_event_queue.serialize.your_serializer_name 的服务并配置

socloz_event_queue:
    serialize: your_serializer_name

队列

如果您想使用其他传输(RabbitMQ、Zer0MQ、Gearman、...),您需要实现 Socloz\EventQueueBundle\Queue\QueueInterface 接口。

interface QueueInterface
{
    public function put($job);

    public function get();

    public function delete($job);
}

get 是一个阻塞调用。只有当 get 不从队列中删除作业时才需要 delete

传输类应注册为名为 socloz_event_queue.queue 的服务。

待办事项

  • 我不会感到羞耻的序列化器
  • Beanstalkd 超时 & 优先级配置

许可证

此扩展包是在 MIT 许可证下发布的(请参阅 LICENSE)。