Skip to content

Commit f2f8d86

Browse files
authored
Merge pull request #18 from dotkernel/audit
fixed inconsistencies with dotkernel/queue repo
2 parents e38f5b7 + 708036f commit f2f8d86

9 files changed

Lines changed: 280 additions & 12 deletions

‎docs/book/v2/control-commands.md‎

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# Available commands and usage
22

3+
## Summary
4+
5+
Three commands — `failed`, `processed`, `inventory` — report on the queue's logs and
6+
current contents; each is available both via the local CLI and over a TCP message to
7+
the queue server.
8+
9+
## Details
10+
311
The commands available are:
412

513
1. `GetFailedMessagesCommand.php (failed)` - returns logs with messages that failed to process (levelName:error)
@@ -13,11 +21,11 @@ The commands can be run in two different ways:
1321
To run the commands via CLI, use the following syntax:
1422

1523
```shell
16-
php bin/cli.php failed --start="yyyy-mm-dd" --end="yyyy-mm-dd" --limit=int
24+
php bin/cli.php failed --start="yyyy-mm-dd[ HH:ii:ss]" --end="yyyy-mm-dd[ HH:ii:ss]" --limit=int
1725
```
1826

1927
```shell
20-
php bin/cli.php processed --start="yyyy-mm-dd" --end="yyyy-mm-dd" --limit=int
28+
php bin/cli.php processed --start="yyyy-mm-dd[ HH:ii:ss]" --end="yyyy-mm-dd[ HH:ii:ss]" --limit=int
2129
```
2230

2331
```shell
@@ -29,11 +37,11 @@ php bin/cli.php inventory
2937
To use commands using TCP messages, the following messages can be used:
3038

3139
```shell
32-
echo "failed --start=yyyy-mm-dd --end=yyyy-mm-dd --limit=days" | socat -t1 - TCP:host:port
40+
echo "failed --start=yyyy-mm-dd[ HH:ii:ss] --end=yyyy-mm-dd[ HH:ii:ss] --limit=days" | socat -t1 - TCP:host:port
3341
```
3442

3543
```shell
36-
echo "processed --start=yyyy-mm-dd --end=yyyy-mm-dd --limit=days" | socat -t1 - TCP:host:port
44+
echo "processed --start=yyyy-mm-dd[ HH:ii:ss] --end=yyyy-mm-dd[ HH:ii:ss] --limit=days" | socat -t1 - TCP:host:port
3745
```
3846

3947
In both cases, the flags are optional. Keep in mind if both `start` and `end` are set, `limit` will not be applied, it's only used when one of `start` or `end` is missing.
@@ -49,3 +57,21 @@ echo "control" | socat -t1 - TCP:host:port
4957
```shell
5058
echo "inventory" | socat -t1 - TCP:host:port
5159
```
60+
61+
## FAQ
62+
63+
**Q: What's the difference between the `failed` and `processed` commands?**
64+
65+
A: `failed` returns log entries at `levelName:error` (messages that failed to
66+
process); `processed` returns entries at `levelName:info` (messages that processed
67+
successfully).
68+
69+
**Q: Can I filter by date and also cap the number of days?**
70+
71+
A: Yes, but not at the same time — `--limit` is only applied when exactly one of
72+
`--start` or `--end` is given; if both are set, `--limit` is ignored.
73+
74+
**Q: How do I quickly verify the queue is processing messages end to end?**
75+
76+
A: Send the `control` message (e.g. `echo "control" | socat -t1 - TCP:host:port`); it
77+
is always logged as processed successfully, giving you a fast round-trip check.

‎docs/book/v2/how-to/communication-with-queue.md‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# COMMUNICATE WITH QUEUE
22

3+
## Summary
4+
5+
Two ways to send a message to Dotkernel Queue from your application: a quick
6+
procedural TCP call, or a reusable service class wired into a Core module.
7+
8+
## Details
9+
310
Communication with the [`Dotkernel Queue`](https://github.com/dotkernel/queue) can be achieved in two different ways: procedural and object-oriented.
411

512
## Procedural approach
@@ -204,3 +211,27 @@ Navigate to your handler, inject the new service and use your custom method wher
204211
protected NotificationService $notificationService
205212
) {
206213
```
214+
215+
> **_NOTE:_** Sending a message only queues it. `src/App/Message/MessageHandler.php`
216+
> only acts on the literal payload values `control` and `retry` out of the box — add
217+
> your own `elseif` branch (or replace the handler) to process the payload your
218+
> service sends, or it will be consumed silently with no effect.
219+
220+
## FAQ
221+
222+
**Q: Which approach should I use — procedural or object-oriented?**
223+
224+
A: Procedural is simplest for a one-off call; the object-oriented
225+
`NotificationService` approach is better once you're sending messages from multiple
226+
places, since it's reusable and easier to maintain.
227+
228+
**Q: Why does my message need to end with a newline?**
229+
230+
A: The Swoole listener uses the newline as the end-of-message marker; without it, the
231+
server keeps waiting for more data and never processes what was sent.
232+
233+
**Q: My message was accepted but nothing happened — why?**
234+
235+
A: Queuing a message only stores it. `src/App/Message/MessageHandler.php` only has
236+
explicit handling for the literal payload values `control` and `retry` out of the
237+
box; anything else needs a handler branch you write yourself.

‎docs/book/v2/how-to/send-emails.md‎

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
# SEND EMAILS
22

3+
## Summary
4+
5+
How to add background email sending to a Dotkernel application by importing Core
6+
into the queue and following the `send-email` branch as a reference implementation.
7+
8+
## Details
9+
310
Using a queuing service solves problems such as server overload. For example, if a server receives a large number of requests, it tries to process them synchronously, resulting in long response times or even server crashes.
411

512
A concrete example is sending emails. While a series of tasks are running on the server, a task such as sending an email is passed to a queue and run in the background so the server can move on to the next task, while the queue composes the email and sends it. Tasks are queued and processed gradually (FIFO), depending on available resources.
613

714
To implement such a service, the [`send-email`](https://github.com/dotkernel/queue/tree/send-email) branch can be taken as a model.
815

9-
> **_NOTE:_** The default branch 1.0 holds only the base code of Queue and provides essential features such as:
16+
> **_NOTE:_** The default branch holds only the base code of Queue and provides essential features such as:
1017
>
1118
> * Adding messages to the queue
1219
> * Retrieving and processing messages (FIFO)
@@ -108,3 +115,23 @@ Inside your `config/autoload` folder create a new file named `mail.global.php`,
108115
Once everything is installed and configured we can move on to handle the data in the queue. In the message handler for example `MessageHandler`, each message from the queue is processed, the email is composed, and then sent. By injecting the required services and using templates, the handler can send emails without blocking the main application, respecting FIFO and asynchronous processing.
109116

110117
In this [file](https://github.com/dotkernel/queue/blob/send-email/src/App/Message/MessageHandler.php) you can follow a simple example of how to create and send an email using data received from the queue inside the handler.
118+
119+
## FAQ
120+
121+
**Q: Do I need to modify the base queue code to send emails?**
122+
123+
A: No — import the `Core` module (copied in or as a submodule) and follow the
124+
`send-email` branch as a model; the default branch already provides message queuing
125+
and FIFO processing.
126+
127+
**Q: What does importing Core actually give the queue?**
128+
129+
A: Access to the main application's entities, services and configuration (cache,
130+
mail, authentication, etc.), so the worker can compose and send real emails using
131+
your existing templates.
132+
133+
**Q: Where do I configure the mailer itself?**
134+
135+
A: Create `config/autoload/mail.global.php` from the example in the `send-email`
136+
branch and fill in your mail settings; the queue uses this to send emails in the
137+
background.

‎docs/book/v2/installation.md‎

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# INSTALLATION
22

3+
## Summary
4+
5+
How to get a working copy of the queue running on the server prepared in
6+
[Server setup](server-setup.md): clone the repository, configure
7+
`config/autoload`, install dependencies, register the systemd daemons, and confirm
8+
the listener responds.
9+
310
## Location
411

512
- Because you are logged in now with the non-root user `dotkernel`, your current server path must be `/home/dotkernel`
@@ -9,15 +16,15 @@
916
## git clone
1017

1118
```shell
12-
git clone -b default-queue https://github.com/dotkernel/queue.git
19+
git clone https://github.com/dotkernel/queue.git
1320
```
1421

1522
> The installation path should be now `/home/dotkernel/queue`
1623
1724
## Prepare `config/autoload` files
1825

1926
- duplicate `local.php.dist` as `local.php`, then fill in the database credentials and set the `$baseUrl`
20-
- duplicate `log.local.dist` as `log.local`
27+
- duplicate `log.local.php.dist` as `log.local.php`
2128
- duplicate `messenger.local.php.dist` as `messenger.local.php`
2229
- duplicate `swoole.local.php.dist` as `swoole.local.php`
2330

@@ -55,7 +62,7 @@ sudo systemctl start swoole.service
5562
```
5663

5764
```shell
58-
sudo systemctl status swoole.service
65+
sudo systemctl status swoole.service
5966
```
6067

6168
## Start the Messenger daemon
@@ -73,13 +80,36 @@ sudo systemctl start messenger.service
7380
```
7481

7582
```shell
76-
sudo systemctl status messenger.service
83+
sudo systemctl status messenger.service
7784
```
7885

7986
### Testing the installation
8087

8188
Send a request from your local machine
8289

8390
```shell
84-
echo "Hello" | socat -T1 - TCP:SERVER-IP:8556`
91+
echo "Hello" | socat -T1 - TCP:SERVER-IP:8556
8592
```
93+
94+
> **_NOTE:_** Any message that is not one of `failed`, `processed` or `inventory` is
95+
> queued twice by design: once with your payload, and once more with the literal
96+
> payload `with 5 seconds delay`, queued 5 seconds later. Expect two entries in
97+
> `inventory`/the logs for every test message you send.
98+
99+
## FAQ
100+
101+
**Q: Which branch should I clone?**
102+
103+
A: Clone without specifying `-b`; this checks out the repository's default branch
104+
instead of pinning to a branch name that can go stale.
105+
106+
**Q: Why does copying `log.local.php.dist` correctly matter?**
107+
108+
A: `config/config.php` only loads local config files that end in `.php`; if the copy
109+
is misnamed the logger silently never loads.
110+
111+
**Q: What should I see after the smoke test?**
112+
113+
A: Two entries appear for the single `echo "Hello"` message you sent — your message,
114+
plus a second, hardcoded `with 5 seconds delay` message queued automatically 5
115+
seconds later.

‎docs/book/v2/messenger-configuration.md‎

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# Messenger Configuration
22

3+
## Summary
4+
5+
Reference for `config/autoload/messenger.local.php`: the Redis transports Symfony
6+
Messenger uses for new and failed messages, their retry strategy, and the two
7+
message streams (`messages`, `failed`) they map to.
8+
9+
## Details
10+
311
```php
412
return [
513
'symfony' => [
@@ -35,7 +43,7 @@ return [
3543
],
3644
],
3745
'dependencies' => [
38-
'factories'> [
46+
'factories' => [
3947
'redis_transport' => [TransportFactory::class, 'redis_transport'],
4048
'failed' => [TransportFactory::class, 'failed'],
4149
SymfonySerializer::class => fn(ContainerInterface $container) => new PhpSerializer(),
@@ -51,3 +59,36 @@ return [
5159
## Dead Letter Queue (DLQ)
5260

5361
DLQ is a dedicated transport where messages are sent when they fail to be processed after a configured number of retries. Each transport can define a retry_strategy specifying the maximum number of retry attempts, delays between retries, and exponential backoff rules. When a message exceeds the allowed retries, it is automatically forwarded to the failure transport and stored in `failed` stream, ensuring that failed messages do not block the queue.
62+
63+
## Application-level retry delays (`fail-safe`)
64+
65+
`config/autoload/local.php` also defines a separate `fail-safe` schedule, used to
66+
delay re-adding a failed message to the queue:
67+
68+
```php
69+
'fail-safe' => [
70+
'first_retry' => 3600000, // 1h
71+
'second_retry' => 43200000, // 12h
72+
'third_retry' => 86400000, // 24h
73+
],
74+
```
75+
76+
This is independent of the transport-level `retry_strategy` above.
77+
78+
## FAQ
79+
80+
**Q: Where do the transport-level retry settings live?**
81+
82+
A: In `config/autoload/messenger.local.php`, under
83+
`symfony.messenger.transports.redis_transport.retry_strategy`.
84+
85+
**Q: What happens once `max_retries` is exceeded?**
86+
87+
A: The message is forwarded to the `failed` transport, defined by
88+
`failure_transport`, and stored in the `failed` Redis stream.
89+
90+
**Q: Is `retry_strategy` the only retry configuration in the project?**
91+
92+
A: No — `config/autoload/local.php` also defines an independent `fail-safe` schedule
93+
(`first_retry`, `second_retry`, `third_retry`) for delaying re-queued messages after
94+
a processing error.

‎docs/book/v2/overview.md‎

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
# Overview
22

3-
> [Dotkernel Queue](https://github.com/dotkernel/dot-queue) is a component based on [**Symfony Messenger**](https://github.com/symfony/messenger) that is used to queue asynchronous tasks.
3+
## Summary
4+
5+
Dotkernel Queue is a Symfony Messenger-based component that lets Mezzio and Laminas
6+
applications hand off slow or unreliable work to background workers instead of
7+
processing it inline.
8+
9+
## Details
10+
11+
> [Dotkernel Queue](https://github.com/dotkernel/queue) is a component based on [**Symfony Messenger**](https://github.com/symfony/messenger) that is used to queue asynchronous tasks.
412
[netglue/laminas-messenger](https://github.com/netglue/laminas-messenger) is an adapter that integrates Symfony Messenger with the [Laminas Service Manager](https://docs.laminas.dev/laminas-servicemanager/) container for Mezzio/Laminas applications.
513

614
Some everyday **operations are time-consuming and resource-intensive**, so it's best if they run on separate machines, decoupled from the regular request-response cycle.
@@ -23,3 +31,21 @@ It allows the main platform to return a response and remain responsive for new r
2331
[![codecov](https://codecov.io/gh/dotkernel/queue/branch/2.0/graph/badge.svg?token=pexSf4wIhc)](https://codecov.io/gh/dotkernel/queue)
2432
[![Qodana](https://github.com/dotkernel/queue/actions/workflows/qodana_code_quality.yml/badge.svg?branch=2.0)](https://github.com/dotkernel/queue/actions/workflows/qodana_code_quality.yml)
2533
[![PHPStan](https://github.com/dotkernel/queue/actions/workflows/static-analysis.yml/badge.svg?branch=2.0)](https://github.com/dotkernel/queue/actions/workflows/static-analysis.yml)
34+
35+
## FAQ
36+
37+
**Q: What is Dotkernel Queue built on?**
38+
39+
A: It's based on Symfony Messenger, integrated into Mezzio/Laminas applications through
40+
the `netglue/laminas-messenger` adapter for the Laminas Service Manager container.
41+
42+
**Q: Why run tasks asynchronously instead of inline?**
43+
44+
A: Time-consuming or resource-intensive operations would otherwise block the
45+
request-response cycle; running them on background workers keeps the main platform
46+
responsive to new requests.
47+
48+
**Q: Where can I find the project's build and license status?**
49+
50+
A: See the badges above, which link to the GitHub issues, forks, stars, license, CI,
51+
code coverage, and static analysis pages for the `dotkernel/queue` repository.

‎docs/book/v2/server-setup.md‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# Server setup
22

3+
## Summary
4+
5+
Step-by-step instructions for provisioning a fresh AlmaLinux 9/10 server with the
6+
users, PHP runtime, Swoole and Redis/Valkey extensions, and firewall rules the queue
7+
daemon needs.
8+
9+
## Details
10+
311
The below instructions were tested only on **AlmaLinux 9** or **10**.
412

513
*For other operating systems, they need to be adapted accordingly.*
@@ -20,6 +28,7 @@ dnf update -y
2028

2129
```shell
2230
useradd dotkernel
31+
useradd --system --no-create-home queue
2332
```
2433

2534
```shell
@@ -54,6 +63,9 @@ sudo dnf install -y https://rpms.remirepo.net/enterprise/remi-release-$(rpm -E %
5463
sudo dnf module enable php:remi-8.5
5564
```
5665

66+
> PHP 8.4 (`php:remi-8.4`) is also supported (`composer.json` allows
67+
> `~8.4.0 || ~8.5.0`); substitute the module version above if you need 8.4.
68+
5769
```shell
5870
sudo dnf install -y php php-cli php-common php-intl
5971
```
@@ -166,3 +178,26 @@ sudo firewall-cmd --reload
166178
```
167179

168180
> NOW THE SERVER IS READY
181+
182+
## FAQ
183+
184+
**Q: Which operating systems does this guide support?**
185+
186+
A: It was tested on AlmaLinux 9 and 10; other operating systems need the steps
187+
adapted accordingly.
188+
189+
**Q: Which PHP versions can I install?**
190+
191+
A: PHP 8.5 (`php:remi-8.5`) is documented here, and PHP 8.4 (`php:remi-8.4`) is also
192+
supported since `composer.json` allows `~8.4.0 || ~8.5.0`.
193+
194+
**Q: Which system users does the queue need?**
195+
196+
A: A sudo-capable `dotkernel` user for administration, and a `queue` system
197+
user/group, which is what the shipped `swoole.service` and `messenger.service` unit
198+
files run as.
199+
200+
**Q: Is the firewall setup mandatory?**
201+
202+
A: No, but it's recommended — it restricts inbound connections on the queue's TCP
203+
port (8556 by default) to specific source IPs.

0 commit comments

Comments
 (0)