Skip to content

Commit 42e0b04

Browse files
vjiksamdark
andauthored
Replace SynchronousAdapter with SynchronousPushHandler (#270)
Co-authored-by: Alexander Makarov <sam@rmcreative.ru>
1 parent 5037487 commit 42e0b04

24 files changed

Lines changed: 254 additions & 280 deletions

.github/workflows/rector-cs.yml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name: Rector + PHP CS Fixer
22

33
on:
4-
pull_request_target:
4+
pull_request:
55
paths:
66
- 'config/**'
77
- 'src/**'
@@ -12,7 +12,7 @@ on:
1212
- '.php-cs-fixer.dist.php'
1313

1414
permissions:
15-
contents: read
15+
contents: write
1616

1717
concurrency:
1818
group: ${{ github.workflow }}-${{ github.ref }}
@@ -21,8 +21,6 @@ concurrency:
2121
jobs:
2222
rector:
2323
uses: yiisoft/actions/.github/workflows/rector-cs.yml@master
24-
secrets:
25-
token: ${{ secrets.YIISOFT_GITHUB_TOKEN }}
2624
with:
2725
repository: ${{ github.event.pull_request.head.repo.full_name }}
2826
php: '8.1'

README.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,11 @@ composer require yiisoft/queue
3636
For production use, you should install an adapter package that matches your message broker ([AMQP](https://github.com/yiisoft/queue-amqp), [Kafka](https://github.com/g41797/queue-kafka), [NATS](https://github.com/g41797/queue-nats), and [others](docs/guide/en/adapter-list.md)).
3737
See the [adapter list](docs/guide/en/adapter-list.md) and follow the adapter-specific documentation for installation and configuration details.
3838

39-
> For development and testing, you can start without an external broker using the built-in [`SynchronousAdapter`](docs/guide/en/adapter-sync.md).
40-
> This adapter processes messages immediately in the same process, so it won't provide true async execution,
41-
> but it's useful for getting started and writing tests.
39+
> If you don't have an external broker — whether for development, testing, or because you want to
40+
> design around `QueueInterface` from day one and add a real broker later — you can run the queue
41+
> in [synchronous mode](docs/guide/en/synchronous-mode.md) (the adapter argument is optional).
42+
> In this mode messages are processed immediately in the same process, so it won't provide true
43+
> async execution, but the code stays the same when you switch to a real adapter.
4244
4345
### 2. Configure the queue
4446

@@ -127,7 +129,7 @@ By default, Yii Framework uses [yiisoft/yii-console](https://github.com/yiisoft/
127129
128130
See [Console commands](docs/guide/en/console-commands.md) for more details.
129131
130-
> In case you're using the `SynchronousAdapter` for development purposes, you should not use these commands, as you have no asynchronous processing available. The messages are processed immediately when pushed.
132+
> In case you're running the queue in synchronous mode (no adapter), `queue:listen` logs an info message and exits. The messages are processed immediately when pushed.
131133
132134
## Documentation
133135

docs/guide/en/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
- [Prerequisites and installation](prerequisites-and-installation.md)
66
- [Configuration with yiisoft/config](configuration-with-config.md)
77
- [Adapter list](adapter-list.md)
8-
- [Synchronous adapter](adapter-sync.md)
8+
- [Synchronous mode](synchronous-mode.md)
99
- [Queue names](queue-names.md)
1010

1111
## Build and handle messages

docs/guide/en/adapter-list.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
Queue Adapters
2-
-------------
1+
# Queue Adapters
32

4-
* [Synchronous](adapter-sync.md) - adapter for development and test environments
5-
* [AMQP](https://github.com/yiisoft/queue-amqp) - adapter over AMQP protocol via [amqplib](https://github.com/php-amqplib/php-amqplib)
3+
If you don't need (or don't yet have) a real broker, the queue can be used in
4+
[synchronous mode](synchronous-mode.md) — no adapter is required.
5+
6+
For asynchronous processing pick one of the adapters below.
67

8+
* [AMQP](https://github.com/yiisoft/queue-amqp) - adapter over AMQP protocol via [amqplib](https://github.com/php-amqplib/php-amqplib)
79

810
There are other queue adapters contributed and maintained by the community and available on GitHub, such as:
911
* [NATS](https://github.com/g41797/queue-nats) - [NATS](https://nats.io/) JetStream adapter

docs/guide/en/adapter-sync.md

Lines changed: 0 additions & 21 deletions
This file was deleted.

docs/guide/en/configuration-manual.md

Lines changed: 3 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ To use the queue, you need to create instances of the following classes:
1616
use Psr\Container\ContainerInterface;
1717
use Psr\Log\NullLogger;
1818
use Yiisoft\Injector\Injector;
19-
use Yiisoft\Queue\Adapter\SynchronousAdapter;
2019
use Yiisoft\Queue\Cli\SimpleLoop;
2120
use Yiisoft\Queue\Middleware\CallableFactory;
2221
use Yiisoft\Queue\Middleware\Consume\ConsumeMiddlewareDispatcher;
@@ -70,49 +69,23 @@ $worker = new Worker(
7069
// Create loop (SignalLoop requires ext-pcntl; SimpleLoop works without it)
7170
$loop = new SimpleLoop();
7271

73-
// Create queue (adapter is wired in a second step due to mutual dependency)
72+
// Create queue. Without an adapter the queue runs in synchronous mode (messages are processed
73+
// immediately on push). Pass an adapter (e.g., AMQP, Redis) for asynchronous processing.
7474
$queue = new Queue(
7575
$worker,
7676
$loop,
7777
$logger,
7878
$pushMiddlewareDispatcher,
7979
);
8080

81-
// SynchronousAdapter needs a queue reference — create it after the queue
82-
$adapter = new SynchronousAdapter($worker, $queue);
83-
84-
// Attach the adapter to the queue (returns a new Queue instance)
85-
$queue = $queue->withAdapter($adapter);
86-
8781
// Now you can push messages
8882
$message = new \Yiisoft\Queue\Message\Message('file-download', ['url' => 'https://example.com/file.pdf']);
8983
$queue->push($message);
9084
```
9185

9286
## Using Queue Provider
9387

94-
For multiple queue names, use `AdapterFactoryQueueProvider` (maps queue names to adapter definitions) or `PredefinedQueueProvider` (maps queue names to pre-built queue instances):
95-
96-
```php
97-
use Yiisoft\Queue\Provider\AdapterFactoryQueueProvider;
98-
use Yiisoft\Queue\Adapter\SynchronousAdapter;
99-
100-
// AdapterFactoryQueueProvider: each queue name maps to an adapter definition.
101-
// The provider wraps each adapter in a Queue with the given name.
102-
$definitions = [
103-
'queue1' => new SynchronousAdapter($worker, $queue),
104-
'queue2' => SynchronousAdapter::class,
105-
];
106-
107-
$provider = new AdapterFactoryQueueProvider(
108-
$queue,
109-
$definitions,
110-
$container,
111-
);
112-
113-
$queueForQueue1 = $provider->get('queue1');
114-
$queueForQueue2 = $provider->get('queue2');
115-
```
88+
For multiple queue names, use `PredefinedQueueProvider` (maps queue names to pre-built queue instances):
11689

11790
```php
11891
use Yiisoft\Queue\Provider\PredefinedQueueProvider;

docs/guide/en/configuration-with-config.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@ Advanced applications eventually need the following tweaks:
1515
- **Named handlers or callable definitions** — map a short message type to a callable in [`yiisoft/queue.handlers` config](message-handler-advanced.md) when another application is the message producer and you cannot use FQCN as message type.
1616
- **Middleware pipelines** — adjust push/consume/failure behavior: collect metrics, modify messages, and so on. See [Middleware pipelines](middleware-pipelines.md) for details.
1717

18-
For development and testing you can start with the synchronous adapter.
19-
For production you have to use a [real backend adapter](adapter-list.md) (AMQP, Kafka, SQS, etc.). If you do not have any preference, it's simpler to start with [yiisoft/queue-amqp](https://github.com/yiisoft/queue-amqp) and [RabbitMQ](https://www.rabbitmq.com/).
18+
If you don't have a broker yet (for development, testing, or as a stepping stone before introducing
19+
async processing), you can run the queue in [synchronous mode](synchronous-mode.md).
20+
For real asynchronous processing pick a [backend adapter](adapter-list.md) (AMQP, Kafka, SQS, etc.). If you do not have any preference, it's simpler to start with [yiisoft/queue-amqp](https://github.com/yiisoft/queue-amqp) and [RabbitMQ](https://www.rabbitmq.com/).

docs/guide/en/console-commands.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ The following command launches a daemon, which infinitely consumes messages from
3333
yii queue:listen [queueName]
3434
```
3535
36+
> **Note:** If the queue is not configured with an adapter (synchronous mode), the command logs an info message and exits gracefully.
37+
3638
## 3. Listen to multiple queues
3739
3840
The following command iterates through multiple queues and is meant to be used in development environment only, as it consumes a lot of CPU for iterating through queues. You can pass to it:

docs/guide/en/message-status.md

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ The API surface is:
77
- `QueueInterface::status(string|int $id): MessageStatus`
88
- `AdapterInterface::status(string|int $id): MessageStatus`
99

10-
Status tracking support depends on the adapter. If an adapter doesn't keep status history, calling `status()` with that ID will throw `InvalidArgumentException`.
10+
Status tracking support depends on the adapter. If an adapter doesn't support status tracking or can't find the message by ID, it returns `MessageStatus::NOT_FOUND`.
1111

1212
## Getting a message ID
1313

@@ -30,6 +30,9 @@ The ID type (`string` or `int`) and how long it stays queryable are adapter-spec
3030

3131
Statuses are represented by the `Yiisoft\Queue\MessageStatus` enum:
3232

33+
- `MessageStatus::NOT_FOUND`
34+
The message is not known to the queue, or the adapter doesn't support status tracking.
35+
3336
- `MessageStatus::WAITING`
3437
The message is in the queue and has not been picked up yet.
3538

@@ -42,7 +45,7 @@ Statuses are represented by the `Yiisoft\Queue\MessageStatus` enum:
4245
In addition to enum cases, `MessageStatus` provides a string key via `MessageStatus::key()`:
4346

4447
```php
45-
$statusKey = $status->key(); // "waiting", "reserved" or "done"
48+
$statusKey = $status->key(); // "not-found", "waiting", "reserved" or "done"
4649
```
4750

4851
## Querying a status
@@ -73,10 +76,10 @@ if ($status === MessageStatus::DONE) {
7376
}
7477
```
7578

76-
## Errors and edge cases
79+
## Edge cases
7780

78-
- **Unknown ID**
79-
If an adapter can't find the message by ID, it must throw `InvalidArgumentException`.
81+
- **Unknown ID or unsupported tracking**
82+
If an adapter doesn't support status tracking or can't find the message by ID, it returns `MessageStatus::NOT_FOUND`.
8083

8184
- **Timing**
8285
`RESERVED` can be short-lived and difficult to observe: depending on the adapter, a message may move from `WAITING` to `RESERVED` and then to `DONE` quickly.

docs/guide/en/queue-names-advanced.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ $provider = new QueueFactoryProvider(
5858
[
5959
'emails' => [
6060
'class' => Queue::class,
61-
'__construct()' => [$worker, $pushDispatcher, $eventDispatcher, $adapter],
61+
'__construct()' => [$worker, $loop, $logger, $pushDispatcher, $adapter],
6262
],
6363
],
6464
$container,

0 commit comments

Comments
 (0)