vivait/delayed-event-bundle

一个延迟事件在可配置的时间段(例如24小时)的事件包


README

在原始事件后任意时间段触发一个Symfony事件

配置服务

vivait_delayed_event:
    queue_transport: beanstalkd # default

Beanstalkd队列传输

这依赖于 pheanstalk 已经安装并设置在你的配置中。你可以使用 configuration 参数向beanstalk队列传递额外信息

注意:TTR(任务尝试时间)是指一个进程在真正重试之前可以运行的时间,如果它太短,则存在一个真实的情况,即一个工作将处理两次。

vivait_delayed_event:
    queue_transport:
        name: beanstalkd
        configuration:
            tube: my_tube
            ttr: 60

创建一个延迟事件

而不是用内核标签标记事件,用 delayed_event 标签标记事件并提供一个延迟

# app/config/services.yml
services:
    app.your_listener_name:
        class: AppBundle\EventListener\AcmeListener
        tags:
            - { name: delayed_event.event_listener, delay: '24 hours', event: app.my_event, method: onMyEvent }

默认情况下,任何整数都将被视为秒。该包将使用 PHP的文本日期时间解析 将文本日期时间字符串解析为秒,如上例所示。

转换器

如果你正在延迟一个事件,而不是存储事件发生时实体的确切状态,你可能希望接收实体的最新版本。该包允许使用转换器,它们在序列化事件属性之前运行。默认情况下,该包启用了一个实体转换器,它将检测事件中的任何实体并存储一个实体引用。这意味着当实体被反序列化以延迟事件时,将从一个数据库中加载一个新鲜实体。

你可以在全局级别上启用/禁用转换器

# app/config.yml
vivait_delayed_event:
    storage: delayed_event_cache
    transformers:
        doctrine: disabled

你还可以在标记事件监听器时启用/禁用它们

# app/config/services.yml
services:
    app.your_listener_name:
        class: AppBundle\EventListener\AcmeListener
        tags:
            - {
                name: delayed_event.event_listener, delay: '24 hours', event: app.my_event, method: onMyEvent,
                transformers: [doctrine]
            }

注意: enabled 部分是可选的,在上面的例子中已经省略,以简化内容。

你可以通过实现 TransformerInterface 接口创建自定义转换器,如下所示

class AcmeTransformer implements TransformerInterface
{
    /**
* @param ReflectionProperty $property
 * @return bool
*/public function supports(\ReflectionProperty $property) {
        $property->getValue();
        return is_object($data) && $this->doctrine->contains($data);
    }

    /**
* @param $data
 * @return array
*/public function serialize($data)
    {
        // Get the ID
        $id = $this->doctrine->getMetaData($data)->getIdentifierFieldNames();

        $class = get_class($data);

        /* @var UnitOfWork $uow */
        $uow = $this->doctrine->getUnitOfWork();
        $id = $uow->getDocumentIdentifier($data);

        return [
            $class,
            $id
        ];
    }

    /**
* @param $data
 * @return mixed
*/public function deserialize($data)
    {
        [$class, $id] = $data;
        return $this->doctrine->getRepository($class)->find($id);
    }
}

然后你必须标记自定义转换器

# app/config/services.yml
services:
    app.your_transformer_name:
        class: AppBundle\EventTransformer\AcmeTransformer
        tags:
            - { name: your_transformer_name }