A Symfony2 bundle to enable asynchronous handling of events
PHP
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.
Command
DependencyInjection
Event
Queue
Resources/config
Serialize
Tests/Queue
Worker
LICENSE
README.md
SoclozEventQueueBundle.php
composer.json

README.md

SoclozEventQueueBundle

A Symfony2 bundle that enable asynchonous execution of event listeners.

As long as some conditions are met, no code changes are required for an application to use the bundle.

The bundle is made of two parts : a listener and a worker.

The listener :

  • is registered for the configured event, with maximum priority,
  • stops propagation of those events,
  • sends the serialized events to the queue.

The worker :

  • builds the list of application listeners for the configured event,
  • listens to the queue and deserializes received events,
  • executes the listeners.

Dependencies

  • beanstalk - other queues can be added

Setup

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

Other possible configuration options (with default values) :

socloz_event_queue:
    beanstalkd:
        port: 11300
        persistent: true
        timeout: 1
  • start the worker (a process management daemon, like supervisord is recommended) :
$ app/console socloz:event_queue:worker [stop_after]

If used, stop_after enables to worker to stop after a certain number of seconds (warning : the test is done after a job has been executed).

Serializers

Events need to be serialized before being sent. Objects coming from the ORM/ODM usually cannot be serialized/deserialized using PHP builtin classes, therefore the bundle uses dedicated serializers.

For now, 2 basic serializers exist :

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

They assume :

  • that a getId method exists for ORM/ODM objects,
  • that all objects having a getId method come from the ORM/ODM,
  • that objects have been saved before dispatching the event (the remote listener instantiates objects from the DB),
  • that events can be created using the constructor without other method calls,
  • that constructor parameters have the same name as class attributes.

I did not have time/wasn't able to find a solution for those. Feel free to contribute better serializers !

ReflectionClass::newInstanceWithoutConstructor would help, but has only be added in 5.4. Class specific serializers, built during warm-up, would also improve performance if you need to forward a lot of events.

Example event class :

<?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;
    }
}

If you need a serializer, it needs to implement the Socloz\EventQueueBundle\Serialize\SerializeInterface interface.

interface SerializeInterface
{
    public function serialize($event);

    public function deserialize($data);
}

It then needs to be registered as a service named socloz_event_queue.serialize.your_serializer_name and configured :

socloz_event_queue:
    serialize: your_serializer_name

Queue

If you want to use another transport (RabbitMQ, Zer0MQ, Gearman, ...), you need to implement the Socloz\EventQueueBundle\Queue\QueueInterface interface.

interface QueueInterface
{
    public function put($job);

    public function get();

    public function delete($job);
}

get is a blocking call. delete is only required if get does not remove jobs from the queue.

The transport class should be registered as a service named socloz_event_queue.queue.

TODO

  • Serializers I wouldn't be ashamed of
  • Beanstalkd timeout & priority configuration

License

This bundle is released under the MIT license (see LICENSE).