Skip to content

Commit 648b92d

Browse files
authored
feat(core): middleware introduced (#19)
* feat(core): middleware introduced & RateLimiter installed * refactor(middleware): improvements * refactor(core): improvements * ci(daily): pipeline renamed * refactor(core): improvements * build(composer): rollback * refactor(core): middleware introduced * ci(infection): covered msi moved to 85 * tests(core): improvements * tests(middleware): improvements * refactor(core): improvements * fix(tests): CommandTester * refactor(command): display improved * refactor(core): improvements * tests(core): improvements * refactor(core): improvements * refacto(middleware): ordered middleware introduced * tests(bridge): doctrine subscriber * refactor(core): improvements * refactor(core): improvements * refactor(core): improvements * refactor(bridge): Doctrine improved * refactor(worker): improvements * ci(rector): analysis rollback * refactor(middleware): fix on array_filter * refactor(core): yield added * refactor(core): reviews * refactor(scheduler): getDueTasks() improvements * doc(middleware): improvements on order * refactor(middleware): MaxExecutionMiddleware
1 parent a0df2cc commit 648b92d

File tree

125 files changed

+3349
-615
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

125 files changed

+3349
-615
lines changed

.github/workflows/daily.yml

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: SchedulerBundle - Daily
1+
name: Daily
22
on:
33
schedule:
44
- cron: "0 0 * * *"
@@ -65,9 +65,13 @@ jobs:
6565
- name: Rector
6666
run: php vendor/bin/rector process --dry-run --clear-cache
6767

68-
# # —— PHPStan ———————————————————————————————————————————————————————
69-
# - name: PHPStan
70-
# run: php vendor/bin/phpstan analyze
68+
# —— Psalm —————————————————————————————————————————————————————————
69+
- name: Run Psalm
70+
run: php vendor/bin/psalm
71+
72+
# —— PHPStan ———————————————————————————————————————————————————————
73+
- name: PHPStan
74+
run: php vendor/bin/phpstan analyze --xdebug
7175

7276
# —— PHPUnit ———————————————————————————————————————————————————————
7377
- name: PHPUnit
@@ -77,7 +81,7 @@ jobs:
7781

7882
# —— Infection —————————————————————————————————————————————————————
7983
- name: Infection
80-
run: php vendor/bin/infection --no-progress --min-covered-msi=80 --min-msi=75 --show-mutations --threads=4
84+
run: php vendor/bin/infection --no-progress --min-covered-msi=85 --min-msi=80 --show-mutations --threads=4
8185
env:
8286
SCHEDULER_REDIS_DSN: redis://127.0.0.1:6379/_symfony_scheduler_tasks
8387
INFECTION_BADGE_API_KEY: ${{ secrets.INFECTION_BADGE_API_KEY }}

.github/workflows/infection.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ jobs:
4141
composer-options: "--prefer-stable"
4242

4343
- name: Run Infection
44-
run: php vendor/bin/infection --no-progress --min-covered-msi=80 --min-msi=75 --show-mutations --threads=4
44+
run: php vendor/bin/infection --no-progress --min-covered-msi=85 --min-msi=80 --show-mutations --threads=4
4545
env:
4646
SCHEDULER_REDIS_DSN: redis://127.0.0.1:6379/_symfony_scheduler_tasks
4747
INFECTION_BADGE_API_KEY: ${{ secrets.INFECTION_BADGE_API_KEY }}

.github/workflows/static-analysis.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,7 @@ jobs:
3737
composer-options: "--prefer-stable"
3838

3939
- name: Run PHPStan
40-
run: php vendor/bin/phpstan analyze
40+
run: php vendor/bin/phpstan analyze --xdebug
41+
42+
- name: Run Psalm
43+
run: php vendor/bin/psalm

CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,18 @@ CHANGELOG
55
-----
66

77
* Doctrine dependencies updated (see https://github.com/Guikingone/SchedulerBundle/pull/17)
8+
* Middleware introduced (see https://github.com/Guikingone/SchedulerBundle/pull/19)
9+
* `Scheduler::yieldTask()` introduced (see https://github.com/Guikingone/SchedulerBundle/pull/19)
10+
* `scheduler:yield` command added (see https://github.com/Guikingone/SchedulerBundle/pull/19)
11+
* Documentation improvements (see https://github.com/Guikingone/SchedulerBundle/pull/19)
812

913
0.2.0
1014
-----
1115

1216
* Task notifications added (see https://github.com/Guikingone/SchedulerBundle/pull/1)
1317
* Task & Worker lifecycle logs added (see https://github.com/Guikingone/SchedulerBundle/pull/5)
1418
* PHP 7.2 & 7.3 support dropped (see https://github.com/Guikingone/SchedulerBundle/pull/13)
15-
* PHP 8.0 support added (see https://github.com/Guikingone/SschedulerBundle/pull/13)
19+
* PHP 8.0 support added (see https://github.com/Guikingone/SchedulerBundle/pull/13)
1620

1721
0.1.0
1822
-----

Makefile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,11 @@ php-cs-fixer-dry:
3434

3535
phpstan: ## Run PHPStan (the configuration must be defined in phpstan.neon)
3636
phpstan: phpstan.neon.dist
37-
$(PHP) vendor/bin/phpstan analyse
37+
$(PHP) vendor/bin/phpstan analyse --memory-limit 2G --xdebug
38+
39+
psalm: ## Run Psalm
40+
psalm: psalm.xml
41+
$(PHP) vendor/bin/psalm --show-info=true
3842

3943
rector-dry: ## Run Rector in --dry-run mode
4044
rector-dry: rector.php

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
![SchedulerBundleHero](assets/SchedulerBundle.png)
22

33
<div align="center">
4-
<img src="https://img.shields.io/github/workflow/status/Guikingone/SchedulerBundle/SchedulerBundle%20-%20Daily?style=flat" alt="Daily build status">
4+
<img src="https://img.shields.io/github/workflow/status/Guikingone/SchedulerBundle/Daily?style=flat" alt="Daily build status">
55
<img src="https://img.shields.io/packagist/v/guikingone/scheduler-bundle?style=flat" alt="Current bundle version">
66
<img src="https://img.shields.io/packagist/php-v/guikingone/scheduler-bundle?style=flat" alt="PHP version requirement">
77
<img src="https://img.shields.io/symfony/i/grade/825be328-29f8-44f7-a750-f82818ae9111?style=flat" alt="Symfony Insight">
@@ -85,3 +85,6 @@ When a task is configured, time to execute it, two approaches can be used:
8585
* [Policies](doc/policies.md)
8686
* [Runners](doc/runners.md)
8787
* [Worker](doc/worker.md)
88+
* [Scheduler](doc/scheduler.md)
89+
* [Middleware](doc/middleware.md)
90+
* [Tests](doc/test.md)

composer.json

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
"authors": [
88
{
99
"name": "Guillaume Loulier",
10-
"email": "[email protected]"
10+
"email": "[email protected]",
11+
"homepage": "https://www.guillaumeloulier.fr/"
1112
}
1213
],
1314
"autoload": {
@@ -27,6 +28,7 @@
2728
"SchedulerBundle\\Exception\\": "src/Exception/",
2829
"SchedulerBundle\\Expression\\": "src/Expression/",
2930
"SchedulerBundle\\Messenger\\": "src/Messenger/",
31+
"SchedulerBundle\\Middleware\\": "src/Middleware/",
3032
"SchedulerBundle\\Runner\\": "src/Runner/",
3133
"SchedulerBundle\\SchedulePolicy\\": "src/SchedulePolicy/",
3234
"SchedulerBundle\\Serializer\\": "src/Serializer/",
@@ -56,6 +58,7 @@
5658
"Tests\\SchedulerBundle\\EventListener\\": "tests/EventListener/",
5759
"Tests\\SchedulerBundle\\Expression\\": "tests/Expression/",
5860
"Tests\\SchedulerBundle\\Messenger\\": "tests/Messenger/",
61+
"Tests\\SchedulerBundle\\Middleware\\": "tests/Middleware/",
5962
"Tests\\SchedulerBundle\\Runner\\": "tests/Runner/",
6063
"Tests\\SchedulerBundle\\Runner\\Runner\\": "tests/Runner/Assets/",
6164
"Tests\\SchedulerBundle\\SchedulePolicy\\": "tests/SchedulePolicy/",
@@ -77,8 +80,8 @@
7780
"require": {
7881
"php": ">=7.4",
7982
"ext-json": "*",
80-
"dragonmantank/cron-expression": "^3.0",
81-
"psr/log": "~1.0",
83+
"dragonmantank/cron-expression": "^3.1",
84+
"psr/log": "^1.0",
8285
"symfony/config": "^5.2",
8386
"symfony/console": "^5.2",
8487
"symfony/event-dispatcher": "^5.2",
@@ -101,18 +104,21 @@
101104
"infection/infection": "^0.21",
102105
"nikic/php-parser": "^4.10.2",
103106
"phpstan/phpstan": "^0.12",
104-
"phpstan/phpstan-phpunit": "^0.12",
105107
"phpstan/phpstan-doctrine": "^0.12.19",
108+
"phpstan/phpstan-phpunit": "^0.12",
109+
"phpstan/phpstan-symfony": "^0.12.19",
106110
"phpunit/phpunit": "^9.5",
107111
"psalm/plugin-phpunit": "^0.15",
108112
"psr/cache": "^1.0",
109113
"rector/rector": "^0.9.18",
114+
"roave/no-leaks": "^1.2",
110115
"symfony/dependency-injection": "^5.2",
111116
"symfony/framework-bundle": "^5.2",
112117
"symfony/http-client": "^5.2",
113118
"symfony/http-kernel": "^5.2",
114119
"symfony/messenger": "^5.2",
115120
"symfony/notifier": "^5.2",
121+
"symfony/rate-limiter": "^5.2",
116122
"thecodingmachine/safe": "^1.3.3",
117123
"vimeo/psalm": "^4.4"
118124
},

doc/command.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,44 @@ _Description: Retry a task that has failed during execution_
4141
```bash
4242
$ bin/console scheduler:retry:failed **taskname**
4343
```
44+
45+
## Yielding a task
46+
47+
_Introduced in `0.3`_
48+
49+
_Description: Yield a task_
50+
51+
```bash
52+
$ bin/console scheduler:yield **task**
53+
```
54+
55+
### Example
56+
57+
Using the `--force` option:
58+
59+
```bash
60+
$ bin/console scheduler:retry foo --force
61+
62+
[OK] The task "foo" has been yielded
63+
```
64+
65+
Using the question:
66+
67+
```bash
68+
$ bin/console scheduler:retry foo --force
69+
70+
Do you want to yield this task? (yes/no) [no]:
71+
> yes
72+
73+
[OK] The task "foo" has been yielded
74+
```
75+
76+
Using the `--force` option and the `--async` one:
77+
78+
```bash
79+
$ bin/console scheduler:retry foo --async --force
80+
81+
[OK] The task "foo" has been yielded
82+
```
83+
**PS: Using the `async` option forces the scheduler to call the message bus, this approach requires
84+
that you call the related command from it to consume messages**

doc/middleware.md

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
# Middleware
2+
3+
_Introduced in `0.3`_
4+
5+
- [Scheduling](#Scheduling)
6+
- [Execution](#Execution)
7+
- [Order](#Order)
8+
9+
This bundle defines middleware related to execution and scheduling phases.
10+
11+
Middlewares are "man in the middle" that allows you to interact with the task
12+
that is about to be scheduled/executed or even after the scheduling/execution.
13+
14+
There are two types of middleware:
15+
16+
- Pre_*Action*_Middleware
17+
- Post_*Action*_Middleware
18+
19+
Both are called by [SchedulerMiddlewareStack](../src/Middleware/SchedulerMiddlewareStack.php) and/or
20+
[WorkerMiddlewareStack](../src/Middleware/WorkerMiddlewareStack.php).
21+
22+
## Scheduling
23+
24+
The [SchedulerMiddlewareStack](../src/Middleware/SchedulerMiddlewareStack.php) allows to interact
25+
during the scheduling process, some points to keep in mind:
26+
27+
- If an error/exception occurs/is thrown during the `preScheduling` process, the scheduling process is stopped.
28+
- Same thing goes for `postScheduling`.
29+
30+
Defining a "scheduling middleware" is pretty straight-forward:
31+
32+
```php
33+
<?php
34+
35+
declare(strict_types=1);
36+
37+
namespace App\Middleware;
38+
39+
use SchedulerBundle\Middleware\PostSchedulingMiddlewareInterface;
40+
use SchedulerBundle\Middleware\PreSchedulingMiddlewareInterface;
41+
use SchedulerBundle\SchedulerInterface;
42+
use SchedulerBundle\Task\TaskInterface;
43+
44+
final class FooMiddleware implements PreSchedulingMiddlewareInterface, PostSchedulingMiddlewareInterface
45+
{
46+
public function preScheduling(TaskInterface $task, SchedulerInterface $scheduler) : void
47+
{
48+
}
49+
50+
public function postScheduling(TaskInterface $task, SchedulerInterface $scheduler) : void
51+
{
52+
}
53+
}
54+
```
55+
56+
Both methods receive the current task (before scheduling it and sending it through transport) along with the scheduler.
57+
58+
## Execution
59+
60+
The [WorkerMiddlewareStack](../src/Middleware/WorkerMiddlewareStack.php) allows to interact
61+
during the execution process, some points to keep in mind:
62+
63+
- If an error/exception occurs/is thrown during the `preExecute` process,
64+
the execution process is stopped then the task is stored in the failed task list.
65+
- Same thing goes for `postExecute`.
66+
67+
Defining an "execution middleware" is pretty straight-forward:
68+
69+
```php
70+
<?php
71+
72+
declare(strict_types=1);
73+
74+
namespace App\Middleware;
75+
76+
use SchedulerBundle\Middleware\PostExecutionMiddlewareInterface;
77+
use SchedulerBundle\Middleware\PreExecutionMiddlewareInterface;
78+
use SchedulerBundle\Task\TaskInterface;
79+
80+
final class FooMiddleware implements PreExecutionMiddlewareInterface, PostExecutionMiddlewareInterface
81+
{
82+
public function preExecute(TaskInterface $task, array $extraOptions = []): void
83+
{
84+
}
85+
86+
public function postExecute(TaskInterface $task) : void
87+
{
88+
}
89+
}
90+
```
91+
92+
Both methods receive the current task.
93+
94+
### Extra information
95+
96+
- Implementing both interfaces for each middleware is not required, your middleware can be focused on a single one.
97+
- A middleware can interact during both processes by implementing the desired interfaces,
98+
each stack sorts related middlewares before interacting with them.
99+
100+
## Order
101+
102+
Middlewares can be ordered using an integer, this approach allows to define a specific order
103+
when executing middlewares, this can be useful to prioritize specific behaviour.
104+
105+
This behaviour is implemented via [OrderedMiddlewareInterface](../src/Middleware/OrderedMiddlewareInterface.php):
106+
107+
```php
108+
<?php
109+
110+
declare(strict_types=1);
111+
112+
use SchedulerBundle\Middleware\OrderedMiddlewareInterface;
113+
114+
final class FooMiddleware implements OrderedMiddlewareInterface
115+
{
116+
public function getPriority() : int
117+
{
118+
return 1;
119+
}
120+
}
121+
```
122+
123+
_Note: The lower the priority, the earlier the middleware is called._

0 commit comments

Comments
 (0)