Have been thinking about Middlewares and how they work. I like them since they are easy to create and the interface is simple, i dont like them when you have functionality that are shared between consuming and producing. Because of that i propose the following.
- Use events where the middlewares are currently used
consume
, produce
and exception
.
- Create a Strategy implementation for executing messages. which will be a layer between the Consumer and calling the method.
- Remove the middleware notion.
This work make the BatchMiddleware look as following (mockup).
<?php
namespace Bernard\EventDispatcher;
use Bernard\Envelope;
use Bernard\Queue;
use Bernard\Batch\Storage;
use Bernard\EventDispatcher;
class BatchListener implements EventSubscriber
{
protected $storage;
public function __construct(Storage $storage)
{
$this->storage;
}
public function onProduce(Envelope $envelope, Queue $queue)
{
if (false == $batch = $event->getEnvelope()->getStamp('batch')) {
return;
}
$this->storage->register($batch);
}
public function onConsume(Envelope $envelope, Queue $queue)
{
if (false == $batch = $event->getEnvelope()->getStamp('batch')) {
return;
}
$this->storage->increment($batch, 'consumed');
}
public function onException(Envelope $envelope, Queue $queue, $exception)
{
if (false == $batch = $event->getEnvelope()->getStamp('batch')) {
return;
}
$this->storage->increment($batch, 'failed');
}
public function subscribe(EventDispatcher $dispatcher)
{
$dispatcher->on('bernard.consume', [$this, 'onConsume']);
$dispatcher->on('bernard.exception', [$this, 'onException']);
$dispatcher->on('bernard.produce', [$this, 'onProduce']);
}
}
The convenience for this is that it will only requirering creating a single class for adding stuff of both the producer and consumer side.
the Strategy is to provide a extension point for executing jobs in different ways suchs as threads or forks with Spork.