phpgears/event-async

事件总线异步装饰器

0.2.1 2019-10-05 13:12 UTC

This package is auto-updated.

Last update: 2024-09-17 06:36:18 UTC


README

PHP version Latest Version License

Build Status Style Check Code Quality Code Coverage

Total Downloads Monthly Downloads

异步事件

事件总线异步装饰器

安装

Composer

composer require phpgears/event-async

用法

需要 composer 自动加载文件

require './vendor/autoload.php';

异步事件总线

异步处理事件的事件总线装饰器

入队

use Gears\Event\Async\AsyncEventBus;
use Gears\Event\Async\Serializer\JsonEventSerializer;
use Gears\Event\Async\Discriminator\ParameterEventDiscriminator;

/* @var \Gears\Event\EventBus $eventBus */

/* @var Gears\Event\Async\EventQueue $eventQueue */
$eventQueue = new CustomEventQueue(new JsonEventSerializer());

$asyncEventBus new AsyncEventBus(
    $eventBus,
    $eventQueue,
    new ParameterEventDiscriminator('async')
);

$asyncEvent = new CustomEvent(['async' => true]);

$asyncEventBus->dispatch($asyncEvent);

请注意,入队过程独立于事件处理,不会阻止事件被处理。事件首先入队,然后像往常一样正常发送到包装的事件总线

出队

这部分高度依赖于您选择的消息队列,尽管可以使用事件序列化器来反序列化队列消息

这只是一个过程的示例

use Gears\Event\Async\ReceivedEvent;
use Gears\Event\Async\Serializer\JsonEventSerializer;

/* @var \Gears\Event\Async\AsyncEventBus $asyncEventBus */
/* @var your_message_queue_manager $queue */

$serializer = new JsonEventSerializer();

while (true) {
  $message = $queue->getMessage();

  if ($message !== null) {
    $event = new ReceivedEvent($serializer->fromSerialized($message));

    $asyncEventBus->dispatch($event);
  }
}

反序列化的事件应该被包装在 Gears\Event\Async\ReceivedEvent 中,以避免在您决定将事件发送到异步事件总线时发生无限循环。 如果您决定在出队侧使用非异步总线,则不需要此包装

判别器

根据任意条件判断事件是否应该入队

本包提供了三个判别器

  • Gears\Event\Async\Discriminator\ArrayEventDiscriminator 如果事件存在于提供的数组中则选择事件
  • Gears\Event\Async\Discriminator\ClassEventDiscriminator 通过事件类或接口选择事件
  • Gears\Event\Async\Discriminator\ParameterEventDiscriminator 通过事件负载参数的存在(可选地,通过其值)选择事件

事件队列

这是负责实际异步处理的部分,通常会将序列化的事件发送到消息队列系统,如 RabbitMQ

本包不提供实现,而是提供了一个抽象基类,以便您可以从中扩展

use Gears\Event\Async\AbstractEventQueue;

class CustomEventQueue extends AbstractEventQueue
{
  public function send(Event $event): void
  {
    // Do the actual enqueue of $this->getSerializedEvent($event);
  }
}

您可以使用 event-async-queue-interop,该工具使用 queue-interop 入队消息

序列化器

抽象事件队列使用序列化器进行事件序列化,以便将其作为字符串消息发送到消息队列

Gears\Event\Async\Serializer\JsonEventSerializer 直接提供作为通用序列化器,以便在事件由其他系统处理时具有最大兼容性

如果您提供的序列化器不适合您的需求,您可以创建自己的序列化器,例如使用 JMS serializer,通过实现 Gears\Event\Async\Serializer\EventSerializer 接口

分布式系统

在分布式系统(如微服务系统)中,事件可以在系统的完全不同的部分进行出队,这部分当然应该了解触发的事件及其内容,但最终可能无法访问事件类本身

例如,在 DDD 上下文中,领域事件的一个有界上下文可能会对另一个完全不同的有界上下文触发的事件做出反应,并且当然无法反序列化原始事件,因为它位于另一个领域

这可以通过两种方式之一来解决:在将消息传递给事件序列化器之前转换消息队列出来的消息,或者更好地通过创建一个自定义的 Gears\Event\Async\Serializer\EventSerializer 来封装此转换

转换可以像更改要重新构建的事件类一样简单

贡献

发现了bug或有功能请求?请提交一个新的问题。在提交之前请先查看现有的问题。

请参阅文件CONTRIBUTING.md

许可证

请查阅源代码中包含的LICENSE文件以获取许可证条款的副本。