Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,10 @@ final class DownloadFileMessage extends Message
Then create a handler that processes it:

```php
use Yiisoft\Queue\Message\Handler\HandlerInterface;
use Yiisoft\Queue\Message\MessageInterface;
use Yiisoft\Queue\Message\MessageHandlerInterface;

final readonly class RemoteFileHandler implements MessageHandlerInterface
final readonly class RemoteFileHandler implements HandlerInterface
{
public function __construct(
private FileDownloader $downloader,
Expand Down
4 changes: 2 additions & 2 deletions config/di.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@
use Yiisoft\Queue\Middleware\Push\PushMiddlewareConfig;
use Yiisoft\Queue\Middleware\Push\PushMiddlewareFactory;
use Yiisoft\Queue\Middleware\Push\PushMiddlewareFactoryInterface;
use Yiisoft\Queue\Message\Handler\HandlerResolver;
use Yiisoft\Queue\Worker\Worker as QueueWorker;
use Yiisoft\Queue\Worker\WorkerInterface;

/* @var array $params */

return [
QueueWorker::class => [
'class' => QueueWorker::class,
HandlerResolver::class => [
'__construct()' => [$params['yiisoft/queue']['handlers']],
],
WorkerInterface::class => QueueWorker::class,
Expand Down
4 changes: 2 additions & 2 deletions config/params.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
use Yiisoft\Queue\Debug\QueueConsumerProviderProxy;
use Yiisoft\Queue\Debug\QueueProducerProviderProxy;
use Yiisoft\Queue\Debug\QueueWorkerInterfaceProxy;
use Yiisoft\Queue\Message\MessageHandlerInterface;
use Yiisoft\Queue\Message\Handler\HandlerInterface;
use Yiisoft\Queue\Message\Serializer\MessageSerializer;
use Yiisoft\Queue\Provider\QueueConsumerProviderInterface;
use Yiisoft\Queue\Provider\QueueProducerProviderInterface;
Expand All @@ -35,7 +35,7 @@
'messages' => [],
/**
* Map of message type to handler. The worker uses this to find the handler for a received message.
* A handler may be a class name implementing {@see MessageHandlerInterface}, a callable, or any definition
* A handler may be a class name implementing {@see HandlerInterface}, a callable, or any definition
* supported by yiisoft/injector. Example:
* [
* 'send-email' => SendEmailHandler::class,
Expand Down
10 changes: 5 additions & 5 deletions docs/guide/en/best-practices.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ This guide covers recommended practices for building reliable and maintainable q
#### Bad

```php
final class ProcessPaymentHandler implements MessageHandlerInterface
final class ProcessPaymentHandler implements HandlerInterface
{
public function handle(MessageInterface $message): void
{
Expand All @@ -24,7 +24,7 @@ final class ProcessPaymentHandler implements MessageHandlerInterface
#### Good

```php
final class ProcessPaymentHandler implements MessageHandlerInterface
final class ProcessPaymentHandler implements HandlerInterface
{
public function handle(MessageInterface $message): void
{
Expand Down Expand Up @@ -58,7 +58,7 @@ Avoid storing per-message state in handler properties. The container may return
#### Bad

```php
final class ProcessPaymentHandler implements MessageHandlerInterface
final class ProcessPaymentHandler implements HandlerInterface
{
private array $processedIds = [];

Expand All @@ -80,7 +80,7 @@ final class ProcessPaymentHandler implements MessageHandlerInterface
#### Good

```php
final class ProcessPaymentHandler implements MessageHandlerInterface
final class ProcessPaymentHandler implements HandlerInterface
{
public function handle(MessageInterface $message): void
{
Expand Down Expand Up @@ -273,7 +273,7 @@ See [Message handler](message-handler.md) for details.

```php
// Metrics collection in every handler
final class EmailHandler implements MessageHandlerInterface
final class EmailHandler implements HandlerInterface
{
public function handle(MessageInterface $message): void
{
Expand Down
7 changes: 2 additions & 5 deletions docs/guide/en/configuration-manual.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ To use the queue, you need to create instances of the following classes:
```php
use Psr\Container\ContainerInterface;
use Psr\Log\NullLogger;
use Yiisoft\Injector\Injector;
use Yiisoft\Queue\Cli\SimpleLoop;
use Yiisoft\Queue\Message\Handler\HandlerResolver;
use Yiisoft\Queue\Middleware\CallableFactory;
use Yiisoft\Queue\Middleware\Consume\ConsumeMiddlewareDispatcher;
use Yiisoft\Queue\Middleware\Consume\ConsumeMiddlewareFactory;
Expand Down Expand Up @@ -57,13 +57,10 @@ $pushMiddlewareConfig = new PushMiddlewareConfig(

// Create worker
$worker = new Worker(
$handlers,
$logger,
new Injector($container),
$container,
$consumeMiddlewareDispatcher,
$failureMiddlewareDispatcher,
$callableFactory,
new HandlerResolver($handlers, $container),
);

// Create loop (SignalLoop requires ext-pcntl; SimpleLoop works without it)
Expand Down
2 changes: 1 addition & 1 deletion docs/guide/en/configuration-with-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ If you are using [yiisoft/config](https://github.com/yiisoft/config) (i.e. insta
In [yiisoft/app](https://github.com/yiisoft/app) / [yiisoft/app-api](https://github.com/yiisoft/app-api) templates you typically add or adjust configuration in `config/params.php`.
If your project structure differs, put configuration into any params config file that is loaded by [yiisoft/config](https://github.com/yiisoft/config).

When your message type equals the FQCN of a handler class that implements `Yiisoft\Queue\Message\MessageHandlerInterface`, nothing else has to be configured: the DI container resolves the class automatically. See [Message handler](message-handler.md) for details and trade-offs.
When your message type equals the FQCN of a handler class that implements `Yiisoft\Queue\Message\Handler\HandlerInterface`, nothing else has to be configured: the DI container resolves the class automatically. See [Message handler](message-handler.md) for details and trade-offs.

Advanced applications eventually need the following tweaks:

Expand Down
8 changes: 4 additions & 4 deletions docs/guide/en/message-handler-advanced.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ For a conceptual overview of what messages and handlers are, see [Messages and h
Handler definitions are configured in:

- `$params['yiisoft/queue']['handlers']` when using [yiisoft/config](https://github.com/yiisoft/config), or
- the `$handlers` argument of `Yiisoft\Queue\Worker\Worker` when creating it manually.
- the `$handlers` argument of `Yiisoft\Queue\Message\Handler\HandlerResolver` when creating it manually.

## Supported handler definition formats

Expand Down Expand Up @@ -76,7 +76,7 @@ return [
];
```

Handler definition should be either an [extended callable definition](./callable-definitions-extended.md) or a container identifier that resolves to a `MessageHandlerInterface` instance.
Handler definition should be either an [extended callable definition](./callable-definitions-extended.md) or a container identifier that resolves to a `HandlerInterface` instance.


## When mapping by short names is a better idea
Expand Down Expand Up @@ -111,7 +111,7 @@ This way external producers never need to know your internal PHP class names.

The worker recognises three callable signatures:

- `MessageHandlerInterface` — implement the interface; the worker calls `handle(MessageInterface $message): void` directly (covered in [Message handler](message-handler.md)).
- `HandlerInterface` — implement the interface; the worker calls `handle(MessageInterface $message): void` directly (covered in [Message handler](message-handler.md)).
- Invokable class — add `__invoke(MessageInterface $message): void`.
- Explicit method — reference as `[HandlerClass::class, 'handle']` with `handle(MessageInterface $message): void` as the entry point.

Expand All @@ -129,4 +129,4 @@ return [
];
```

This config is consumed by the DI definitions from [`config/di.php`](../../../config/di.php) where the `Worker` is constructed with `$params['yiisoft/queue']['handlers']`.
This config is consumed by the DI definitions from [`config/di.php`](../../../config/di.php) where the `HandlerResolver` is constructed with `$params['yiisoft/queue']['handlers']`.
6 changes: 3 additions & 3 deletions docs/guide/en/message-handler.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

> If you are new to the concept of messages and handlers, read [Messages and handlers: concepts](messages-and-handlers.md) first.

The simplest setup requires no configuration at all: create a dedicated class implementing `Yiisoft\Queue\Message\MessageHandlerInterface` and use its FQCN as the message type when pushing a message.
The simplest setup requires no configuration at all: create a dedicated class implementing `Yiisoft\Queue\Message\Handler\HandlerInterface` and use its FQCN as the message type when pushing a message.

## HandlerInterface implementation (without type mapping)

If your handler implements `Yiisoft\Queue\Message\MessageHandlerInterface`, you can use the class FQCN as the message type. The DI container resolves the handler automatically.
If your handler implements `Yiisoft\Queue\Message\Handler\HandlerInterface`, you can use the class FQCN as the message type. The DI container resolves the handler automatically.

> By default the [yiisoft/di](https://github.com/yiisoft/di) container resolves all FQCNs into corresponding class objects.

Expand Down Expand Up @@ -46,7 +46,7 @@ new RemoteFileMessage('https://...');
**Handler**:

```php
final class RemoteFileHandler implements \Yiisoft\Queue\Message\MessageHandlerInterface
final class RemoteFileHandler implements \Yiisoft\Queue\Message\Handler\HandlerInterface
{
public function handle(\Yiisoft\Queue\Message\MessageInterface $message): void
{
Expand Down
2 changes: 1 addition & 1 deletion docs/guide/en/messages-and-handlers.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ The message has no business logic, no dependencies. It is a value object — a t
The handler receives the message and acts on it:

```php
final class SendEmailHandler implements \Yiisoft\Queue\Message\MessageHandlerInterface
final class SendEmailHandler implements \Yiisoft\Queue\Message\Handler\HandlerInterface
{
public function __construct(private Mailer $mailer) {}

Expand Down
6 changes: 3 additions & 3 deletions docs/guide/en/performance-tuning.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public function handle(MessageInterface $message): void

```php
// Bad - accumulates in memory
class Handler implements MessageHandlerInterface
class Handler implements HandlerInterface
{
private static array $cache = [];

Expand All @@ -105,7 +105,7 @@ class Handler implements MessageHandlerInterface
}

// Good - use external cache
class Handler implements MessageHandlerInterface
class Handler implements HandlerInterface
{
public function __construct(private CacheInterface $cache) {}

Expand Down Expand Up @@ -328,7 +328,7 @@ public function handle(MessageInterface $message): void
If your message handler only reads data, use read replicas:

```php
final class GenerateReportHandler implements MessageHandlerInterface
final class GenerateReportHandler implements HandlerInterface
{
public function __construct(
private ConnectionInterface $readDb, // Read replica
Expand Down
29 changes: 29 additions & 0 deletions src/Message/Handler/CallableHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Queue\Message\Handler;

use Yiisoft\Queue\Message\MessageInterface;

/**
* Handles a message by invoking the given callable.
*
* @internal
*/
final class CallableHandler implements HandlerInterface
{
/**
* @param callable $handler Callable invoked to handle a message.
*
* @psalm-param callable(MessageInterface): void $handler
*/
public function __construct(
private readonly mixed $handler,
) {}

public function handle(MessageInterface $message): void
{
($this->handler)($message);
Comment thread
samdark marked this conversation as resolved.
}
}
18 changes: 18 additions & 0 deletions src/Message/Handler/HandlerInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Queue\Message\Handler;

use Yiisoft\Queue\Message\MessageInterface;

/**
* Handles a message.
*/
interface HandlerInterface
{
/**
* Handle the given message.
*/
public function handle(MessageInterface $message): void;
}
25 changes: 25 additions & 0 deletions src/Message/Handler/HandlerNotFoundException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Queue\Message\Handler;

use LogicException;
use Throwable;

use function sprintf;

/**
* Thrown when a handler for the given message type is not found.
*/
final class HandlerNotFoundException extends LogicException
{
public function __construct(string $messageType, int $code = 0, ?Throwable $previous = null)
{
parent::__construct(
sprintf('Queue handler for message type "%s" does not exist.', $messageType),
$code,
$previous,
);
}
}
Loading
Loading