groovycarrot/event-dispatcher

此包的最新版本(dev-master)没有提供许可证信息。

HHVM异步事件调度器。

dev-master 2017-11-19 01:27 UTC

This package is not auto-updated.

Last update: 2024-09-29 03:10:11 UTC


README

用法

添加产品到购物车的一个简单示例:当产品被添加到购物车时,需要发生几件事情;第一项任务是将其添加到当前会话中存储的购物车本身。另一项任务是通知仓库预留库存,以确保可以稍后下订单。在面向对象应用程序的设计中,这些职责应该是分离的,这就是事件发挥作用的地方。

$eventDispatcher = new Dispatcher();

// Tasks must implement the interface EventHandling<AddProductToBasketEvent>.
$eventDispatcher->tasksForEvent(AddProductToBasketEvent::class)
    ->setTask('add_to_basket', new AddProductToBasketTask($session->getBasket()))
    ->setTask('reserve_stock', new WarehouseReserveStockTask());

$product = new TShirt();

$events = await $eventDispatcher->dispatchEvent(new AddProductToBasketEvent($product));

这两个任务 add_to_basketreserve_stock 都以异步方式调用,每个任务接收事件的不同副本。要检查每个任务的事件,dispatchEvent() 返回一个 Map<string, AddProductToBasketEvent>

class HH\Map (2) {
  public $add_to_basket =>
  class AddProductToBasketEvent#2 (1) {
    public $product =>
    class TShirt#1 {}
  }
  public $reserve_stock =>
  class AddProductToBasketEvent#3 (1) {
  public $product =>
    class TShirt#1 {}
  }
}

下订单的一个更复杂示例。

$eventDispatcher->tasksForEvent(PlaceOrderEvent::class)
    ->setTask(
        'process_order',
        // Synchronous task groups will propagate the event to the subtasks in order. Event propagation can
        // be stopped by any of the subtasks, which then triggers the propagation-stopped tasks instead.
        // None of these tasks will prevent other tasks outside of this group from running however.
        SynchronousTaskGroup::newGroup()
            ->addTask(new ProcessPaymentTask(), 0)
            ->addTask(new WarehouseDispatchTask(), 1)
            ->addPropagationStoppedTask(new OrderProcessFailedTask())
            ->addPropagationStoppedTask(new LogToDatabaseTask()))
    ->setTask(
        'logging',
        // Asynchronous task groups will propagate the event to the subtasks at the same time. Each subtasks
        // can modify the event, however stopping propagation is not allowed as it will be unsafe.
        AsynchronousTaskGroup::newGroup()
            ->addTask(new LogToDatabaseTask())
            ->addTask(new LogToFilesystemTask()));

$order = new Order($session->getCustomer(), $session->getBasket());
$event = new PlaceOrderEvent($order);

// Dispatch the event, and return the finished event for a particular task.
$finishedEvent = await $eventDispatcher->dispatchEventForTask($event, 'process_order');

if ($finishedEvent->isPropagationStopped()) {
    // We know if the order failed by checking whether or not the event propagation was stopped.
    // PlaceOrderEvent could implement logic to store error information for handling here.
    print "Sorry, {$finishedEvent->getFailureReason()}";
} else {
    print "Order successful!";
}

// We need to finish any outstanding tasks that were not awaited. This happens automatically when the
// dispatcher is destroyed, however can be triggered manually if the application terminates a
// significant amount of time after these operations.
await $eventDispatcher->flush();

运行测试

hhvm vendor/bin/phpunit