Skip to content

Commit df523a9

Browse files
authored
new doc structure (#361)
* reformat docs * fix dead/wrong links in doc * merge
1 parent bb6ab55 commit df523a9

16 files changed

+1049
-1037
lines changed

Diff for: docs/README.md

+17-1,037
Large diffs are not rendered by default.
File renamed without changes.
File renamed without changes.

Diff for: docs/sections/basic_setup.md

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Basic Setup
2+
3+
## Installation
4+
```
5+
composer require dereuromark/cakephp-queue
6+
```
7+
Load the plugin in your `src/Application.php`'s bootstrap() using:
8+
```php
9+
$this->addPlugin('Queue');
10+
```
11+
If you don't want to also access the backend controller (just using CLI), you need to use
12+
```php
13+
$this->addPlugin('Queue', ['routes' => false]);
14+
```
15+
16+
Important: Make sure to use authentication if you are using the backend. You do not want visitors to be able to browse it.
17+
18+
## Database migration
19+
20+
Run the following command in the CakePHP console to create the tables using the Migrations plugin:
21+
```sh
22+
bin/cake migrations migrate -p Queue
23+
```
24+
25+
Hint: use a native *nix-like or console and not the one provided like from Git (git-bash). This may lead to a non-working `migrations` command.
26+
It is also advised to have the `posix` PHP extension enabled.

Diff for: docs/sections/configuration.md

+165
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
# Configuration
2+
3+
## Global configuration
4+
The plugin allows some simple runtime configuration.
5+
You may create a file called `app_queue.php` inside your `config` folder (NOT the plugins config folder) to set the following values:
6+
7+
- Seconds to sleep() when no executable job is found:
8+
9+
```php
10+
$config['Queue']['sleeptime'] = 10;
11+
```
12+
13+
- Probability in percent of an old job cleanup happening:
14+
15+
```php
16+
$config['Queue']['gcprob'] = 10;
17+
```
18+
19+
- Default timeout after which a job is requeued if the worker doesn't report back:
20+
21+
```php
22+
$config['Queue']['defaultworkertimeout'] = 1800;
23+
```
24+
25+
- Default number of retries if a job fails or times out:
26+
27+
```php
28+
$config['Queue']['defaultworkerretries'] = 3;
29+
```
30+
31+
- Seconds of running time after which the worker will terminate (0 = unlimited):
32+
33+
```php
34+
$config['Queue']['workermaxruntime'] = 120;
35+
```
36+
37+
*Warning:* Do not use 0 if you are using a cronjob to permanantly start a new worker once in a while and if you do not exit on idle.
38+
39+
- Seconds of running time after which the PHP process of the worker will terminate (0 = unlimited):
40+
41+
```php
42+
$config['Queue']['workertimeout'] = 120 * 100;
43+
```
44+
45+
*Warning:* Do not use 0 if you are using a cronjob to permanently start a new worker once in a while and if you do not exit on idle. This is the last defense of the tool to prevent flooding too many processes. So make sure this is long enough to never cut off jobs, but also not too long, so the process count stays in manageable range.
46+
47+
- Should a worker process quit when there are no more tasks for it to execute (true = exit, false = keep running):
48+
49+
```php
50+
$config['Queue']['exitwhennothingtodo'] = false;
51+
```
52+
53+
- Minimum number of seconds before a cleanup run will remove a completed task (set to 0 to disable):
54+
55+
```php
56+
$config['Queue']['cleanuptimeout'] = 2592000; // 30 days
57+
```
58+
59+
- Max workers (per server):
60+
61+
```php
62+
$config['Queue']['maxworkers'] = 3 // Defaults to 1 (single worker can be run per server)
63+
```
64+
65+
- Multi-server setup:
66+
67+
```php
68+
$config['Queue']['multiserver'] = true // Defaults to false (single server)
69+
```
70+
71+
For multiple servers running either CLI/web separately, or even multiple CLI workers on top, make sure to enable this.
72+
73+
- Use a different connection:
74+
75+
```php
76+
$config['Queue']['connection'] = 'custom'; // Defaults to 'default'
77+
```
78+
79+
- Ignore certain task classes to they don't end up in the generated SQL query. Can be used to filter out the example tasks classes shipped with the plugin, if you're not using them:
80+
81+
```php
82+
$config['Queue']['ignoredTasks'] = [
83+
'Queue\Queue\Task\CostsExampleTask',
84+
'Queue\Queue\Task\EmailTask',
85+
'Queue\Queue\Task\ExampleTask',
86+
'Queue\Queue\Task\ExceptionExampleTask',
87+
'Queue\Queue\Task\ExecuteTask',
88+
'Queue\Queue\Task\MonitorExampleTask',
89+
'Queue\Queue\Task\ProgressExampleTask',
90+
'Queue\Queue\Task\RetryExampleTask',
91+
'Queue\Queue\Task\SuperExampleTask',
92+
'Queue\Queue\Task\UniqueExampleTask',
93+
]; // Defaults to []
94+
```
95+
96+
Don't forget to load that config file with `Configure::load('app_queue');` in your bootstrap.
97+
You can also use `$this->addPlugin('Queue', ['bootstrap' => true]);` which will load your `app_queue.php` config file automatically.
98+
99+
Example `app_queue.php`:
100+
101+
```php
102+
return [
103+
'Queue' => [
104+
'workermaxruntime' => 60,
105+
'sleeptime' => 15,
106+
],
107+
];
108+
```
109+
110+
You can also drop the configuration into an existing config file (recommended) that is already been loaded.
111+
The values above are the default settings which apply, when no configuration is found.
112+
113+
### Serializer strategy
114+
By default, the payload data array will be serialized using PHPs native object serializer.
115+
It is recommended to switch to JSON serializing instead, if you don't need to send any actual objects, but only primitive values and arrays.
116+
```php
117+
'Queue' => [
118+
...
119+
'serializerClass' => \Queue\Utility\JsonSerializer::class,
120+
'serializerConfig' => [...],
121+
],
122+
```
123+
This is usually also safer from data perspective.
124+
Any update of your code would not break the process here for queued tasks as no objects could be outdated in serialized payload.
125+
126+
You can also use a custom one as long as it implements the `Queue\Utility\SerializerInterface`.
127+
128+
Note: When using JSON one, make sure to use Email and Mailer tasks only with JSON safe way (not passing actual objects).
129+
130+
### Backend configuration
131+
132+
- isSearchEnabled: Set to false if you do not want search/filtering capability.
133+
This is auto-detected based on [Search](https://github.com/FriendsOfCake/search) plugin being available/loaded if not disabled.
134+
135+
- isStatsEnabled: Set to true to enable. This requires [chart.js](https://github.com/chartjs/Chart.js) asset to be available.
136+
You can also overwrite the template and as such change the asset library as well as the output/chart.
137+
138+
139+
### Configuration tips
140+
141+
For the beginning maybe use not too many runners in parallel, and keep the runtimes rather short while starting new jobs every few minutes.
142+
You can then always increase spawning of runners if there is a shortage.
143+
144+
## Task configuration
145+
146+
You can set two main things on each task as property: timeout and retries.
147+
```php
148+
/**
149+
* Timeout for this task in seconds, after which the task is reassigned to a new worker.
150+
*
151+
* @var int
152+
*/
153+
public $timeout = 120;
154+
155+
/**
156+
* Number of times a failed instance of this task should be restarted before giving up.
157+
*
158+
* @var int
159+
*/
160+
public $retries = 1;
161+
```
162+
Make sure you set the timeout high enough so that it could never run longer than this, otherwise you risk it being re-run while still being run.
163+
It is recommended setting it to at least 2x the maximum possible execution length. See [Concurrent workers](limitations.md)
164+
165+
Set the retries to at least 1, otherwise it will never execute again after failure in the first run.

Diff for: docs/sections/cron.md

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Setting up the trigger cronjob
2+
3+
As outlined in the [book](http://book.cakephp.org/3.0/en/console-and-shells/cron-jobs.html) you can easily set up a cronjob
4+
to start a new worker.
5+
6+
The following example uses "crontab":
7+
8+
*/10 * * * * cd /full/path/to/app && bin/cake queue run -q
9+
10+
Make sure you use `crontab -e -u www-data` to set it up as `www-data` user, and not as root etc.
11+
12+
This would start a new worker every 10 minutes. If you configure your max life time of a worker to 15 minutes, you
13+
got a small overlap where two workers would run simultaneously. If you lower the 10 minutes and raise the lifetime, you
14+
get quite a few overlapping workers and thus more "parallel" processing power.
15+
Play around with it, but just don't shoot over the top.
16+
17+
Also don't forget to set Configure key `'Queue.maxworkers'` to a reasonable value per server.
18+
If, for any reason, some of the jobs should take way longer, you want to avoid additional x workers to be started.
19+
It will then just not start now ones beyond this count until the already running ones are finished.
20+
This is an important server protection to avoid overloading.

Diff for: docs/sections/custom_tasks.md

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Writing your own task
2+
3+
## Baking new Queue task and test
4+
You can bake a new task and its test via
5+
```
6+
bin/cake bake queue_task MyTaskName [-p PluginName]
7+
```
8+
9+
It will generate a `MyTaskNameTask` class in the right namespace.
10+
11+
It will not overwrite existing classes unless you explicitly force this (after prompting).
12+
13+
## Detailed explanation
14+
15+
In most cases you wouldn't want to use the existing task, but just quickly build your own.
16+
Put it into `src/Queue/Task/` as `{YourNameForIt}Task.php`.
17+
18+
You need to at least implement the `run()` method:
19+
```php
20+
namespace App\Queue\Task;
21+
22+
use Queue\Queue\Task;
23+
24+
class YourNameForItTask extends Task {
25+
26+
/**
27+
* @var int
28+
*/
29+
public $timeout = 20;
30+
31+
/**
32+
* @var int
33+
*/
34+
public $retries = 1;
35+
36+
/**
37+
* @param array $data The array passed to QueuedJobsTable::createJob()
38+
* @param int $jobId The id of the QueuedJob entity
39+
* @return void
40+
*/
41+
public function run(array $data, int $jobId): void {
42+
$this->loadModel('FooBars');
43+
if (!$this->FooBars->doSth()) {
44+
throw new RuntimeException('Couldnt do sth.');
45+
}
46+
}
47+
48+
}
49+
```
50+
Make sure it throws an exception with a clear error message in case of failure.
51+
52+
Note: You can use the provided `Queue\Model\QueueException` if you do not need to include a strack trace.
53+
This is usually the default inside custom tasks.
54+
55+
## DI Container Example
56+
57+
If you use the [Dependency Injection Container](https://book.cakephp.org/4/en/development/dependency-injection.html) provided by CakePHP you can also use it inside your tasks.
58+
59+
```php
60+
use Queue\Queue\ServicesTrait;
61+
62+
class MyCustomTask extends Task {
63+
use ServicesTrait;
64+
65+
public function run(array $data, int $jobId): void {
66+
$myService = $this->getService(MyService::class);
67+
}
68+
}
69+
```
70+
71+
As you see here you have to add the [ServicesTrait](https://github.com/dereuromark/cakephp-queue/blob/master/src/Queue/ServicesTrait.php) to your task which then allows you to use the `$this->getService()` method.
File renamed without changes.

Diff for: docs/sections/limitations.md

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Known Limitations
2+
3+
## Concurrent workers may execute the same job multiple times
4+
5+
If you want to use multiple workers, please double-check that all jobs have a high enough timeout (>> 2x max possible execution time of a job). Currently it would otherwise risk the jobs being run multiple times!
6+
7+
## Concurrent workers may execute the same job type multiple times
8+
9+
If you need limiting of how many times a specific job type can be run in parallel, you need to find a custom solution here.

Diff for: docs/sections/misc.md

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Misc
2+
3+
## Logging
4+
5+
By default errors are always logged, and with log enabled also the execution of a job.
6+
Make sure you add this to your config:
7+
```php
8+
'Log' => [
9+
...
10+
'queue' => [
11+
'className' => ...,
12+
'type' => 'queue',
13+
'levels' => ['info'],
14+
'scopes' => ['queue'],
15+
],
16+
],
17+
```
18+
19+
When debugging (not using `--quiet`/`-q`) on "run", it will also log the worker run and end.
20+
21+
You can disable info logging by setting `Queue.log` to `false` in your config.
22+
23+
## Resetting
24+
You can reset all failed jobs from CLI and web backend.
25+
With web backend you can reset specific ones, as well.
26+
27+
From CLI you run this to reset all at once:
28+
```
29+
bin/cake queue reset
30+
```
31+
32+
## Rerunning
33+
You can rerun successfully run jobs if they are not yet cleaned out. Make sure your cleanup timeout is high enough here.
34+
Usually weeks or months is a good balance to have those still stored for this case.
35+
36+
This is especially useful for local development or debugging, though. As you would otherwise have to manually trigger or import the job all the time.
37+
38+
From CLI you run this to rerun all of a specific job type at once:
39+
```
40+
bin/cake queue rerun FooBar
41+
```
42+
You can add an additional reference to rerun a specific job.
43+
44+
## Using custom finder
45+
You can use a convenience finder for tasks that are still queued, that means not yet finished.
46+
```php
47+
$query = $this->QueuedJobs->find('queued')->...;
48+
```
49+
This includes also failed ones if not filtered further using `where()` conditions.
50+
51+
## Notes
52+
53+
`<TaskName>` is the complete class name without the Task suffix (eg. Example or PluginName.Example).
54+
55+
Custom tasks should be placed in `src/Queue/Task/`.
56+
Tasks should be named `SomethingTask` and implement the Queue "Task".
57+
58+
Plugin tasks go in `plugins/PluginName/src/Queue/Task/`.
59+
60+
A detailed Example task can be found in `src/Queue/Task/QueueExampleTask.php` inside this plugin.
61+
62+
Some more tips:
63+
- If you copy an example, do not forget to adapt the namespace ("App")!
64+
- For plugin tasks, make sure to load the plugin using the plugin prefix ("MyPlugin.MyName").

0 commit comments

Comments
 (0)