Skip to content

Instantly share code, notes, and snippets.

@butschster
Last active January 25, 2022 20:40
Show Gist options
  • Save butschster/2c2399b50491209cf74f06964c481b10 to your computer and use it in GitHub Desktop.
Save butschster/2c2399b50491209cf74f06964c481b10 to your computer and use it in GitHub Desktop.
Spiral Framework EventDispatcher
<?php
declare(strict_types=1);
namespace App\Bootloader;
use App\Event\EventHandler;
use App\Event\ShouldBeQueued;
use Spiral\Boot\Bootloader\Bootloader;
use Spiral\Core\Container;
use Spiral\RoadRunnerBridge\Queue\QueueManager;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
final class EventBootloader extends Bootloader
{
protected const SINGLETONS = [
EventDispatcherInterface::class => EventDispatcher::class,
];
protected function listens(): array
{
return [
FooEvent::class => [
BarListener::class
]
];
}
public function boot(EventDispatcherInterface $dispatcher, Container $container): void
{
$events = $this->listens();
foreach ($events as $event => $listeners) {
foreach (array_unique($listeners) as $listener) {
$dispatcher->addListener(
$event,
static function (object $event, string $eventName) use ($listener, $container) {
$connection = is_a($listener, ShouldBeQueued::class) ? 'events' : 'sync';
$queue = $container->get(QueueManager::class)
->getConnection($connection);
$queue->push(EventHandler::class, [
'listener' => $listener,
'method' => 'handle',
'event' => $event,
'eventName' => $eventName,
]);
}
);
}
}
}
}
<?php
declare(strict_types=1);
namespace App\Event;
use Spiral\Core\Container;
use Spiral\Queue\HandlerInterface;
final class EventHandler implements HandlerInterface
{
public function __construct(private Container $container)
{
}
public function handle(string $name, string $id, array $payload): void
{
$event = $payload['event'];
$method = $payload['method'] ?? 'handle';
$listener = $this->container->get($payload['listener']);
$handler = new \ReflectionClass($listener);
$method = $handler->getMethod(
$handler->hasMethod($method) ? $method : '__invoke'
);
$args = $this->container->resolveArguments($method, [
'event' => $event,
]);
$method->invokeArgs($listener, $args);
}
}
<?php
declare(strict_types=1);
use Spiral\RoadRunner\Jobs\Queue\MemoryCreateInfo;
return [
'default' => env('QUEUE_CONNECTION', 'sync'),
'aliases' => [
'events' => 'memory',
],
'connections' => [
'sync' => [
'driver' => 'sync',
],
'memory' => [
'driver' => 'roadrunner',
'connector' => new MemoryCreateInfo('local'),
'consume' => true,
],
],
'registry' => [
'handlers' => [],
],
];
<?php
declare(strict_types=1);
namespace App\Event;
interface ShouldBeQueued
{
}
<?php
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
class FooEvent {
public function __construnct(public strin $msg) {}
}
class BarListener {
public function handle(FooEvent $event) {
echp $event->msg;
}
}
$dispatcher = $container->get(EventDispatcherInterface::class);
$dispatcher->dispatch(new FooEvent('hello'));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment