Swoole Server Tasks

There are times when you might not want to perform certain operations while handling HTTP requests with Responders, for example: sending Mail, storing uploaded files etc.

Server tasks are somewhat in between the message brokers, like RabbitMQ and just using coroutines. Resonance runs tasks on the same server that issued them, but they are also executed in a separate process, in parallel to other tasks that the server could be working on at that moment.

Usage

Distantmagic\Resonance\SwooleTaskServerMessageBus implements Symfony\Component\Messenger\MessageBusInterface, making it compatible with Symfony's Messenger Component

Swoole Server Tasks will only work when the Server is running.

Configuration

You can optionally configure the number of worker processes that Resonance will spawn when the Server starts:

config.ini
ini
[swoole] ; ... task_worker_num = 4 ; ...

Dispatching Tasks

Tasks can be of any type. You do not have to extend any other class or implement any interface.

You need to use SwooleTaskServerMessageBus to dispatch tasks. For example:

app/MyTask.php
php
<?php namespace App; readonly class MyTask { public function __construct(public string $hello) {} }
app/MyClass.php
php
<?php namespace App; use Distantmagic\Resonance\Attribute\Singleton; use Distantmagic\Resonance\Attribute\WantsFeature; use Distantmagic\Resonance\Feature; use Distantmagic\Resonance\SwooleTaskServerMessageBus; #[Singleton] #[WantsFeature(Feature::SwooleTaskServer)] readonly class MyClass { public function __construct( private SwooleTaskServerMessageBus $swooleTaskServerMessageBus ) {} public function doSomething(): void { $this->swooleTaskServerMessageBus->dispatch(new MyTask('world')); } }

Handling Tasks

You need to register a Singleton in the Dependency Injection container. It needs to belong to ServerTaskHandler collection.

HandlesServerTask attribute indicated which task the given handler can process. Task handler needs to either implement the Distantmagic\Resonance\ServerTaskHandlerInterface or extend Distantmagic\Resonance\ServerTaskHandler.

Resonance executes task handlers in a separate process, so unless you exhaust the entire server resources, it won't affect the HTTP response times:

app/MyTaskHandler.php
php
<?php namespace App; use Distantmagic\Resonance\Attribute\GrantsFeature; use Distantmagic\Resonance\Attribute\HandlesServerTask; use Distantmagic\Resonance\Attribute\Singleton; use Distantmagic\Resonance\Feature; use Distantmagic\Resonance\ServerTaskHandler; use Distantmagic\Resonance\SingletonCollection; use Psr\Log\LoggerInterface; /** * @template-extends ServerTaskHandler<MyTask> */ #[GrantsFeature(Feature::SwooleTaskServer)] #[HandlesServerTask(MyTask::class)] #[Singleton(collection: SingletonCollection::ServerTaskHandler)] readonly class MyTaskHandler extends ServerTaskHandler { public function __construct( private LoggerInterface $logger, ) {} /** * @var MyTask $serverTask */ public function handleServerTask(object $serverTask): void { $this->logger->info('Hello '.$serverTask->hi); } }
Edit on GitHub