Skip to content

Commit abea3da

Browse files
authored
feat(task): fluent expression (#26)
* feat(task): fluent expression WIP * refactor(task): expression * refactor(core): expression builders WIP * tests(expression): progress * refactor(core): progress on ExpressionBuilder * refactor(core): ExpressionBuilderr * tests(command): ConsumeTaskCommand improved * tests(bridge): Doctrine connection setUp() improved * tests(transport): LongTailTransport improved * refactor(core): psalm notices improved * refactor(core): improvements * refactor(policy): uasort improved * refactor(core): rector * build(composer): extra deps removed * refactor(core): doc & expression definition improved
1 parent 648b92d commit abea3da

File tree

59 files changed

+1192
-386
lines changed

Some content is hidden

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

59 files changed

+1192
-386
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ CHANGELOG
99
* `Scheduler::yieldTask()` introduced (see https://github.com/Guikingone/SchedulerBundle/pull/19)
1010
* `scheduler:yield` command added (see https://github.com/Guikingone/SchedulerBundle/pull/19)
1111
* Documentation improvements (see https://github.com/Guikingone/SchedulerBundle/pull/19)
12+
* "Fluent" expressions (see https://github.com/Guikingone/SchedulerBundle/pull/26)
1213

1314
0.2.0
1415
-----

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ When a task is configured, time to execute it, two approaches can be used:
7676
## Documentation
7777

7878
* [Usage](doc/usage.md)
79+
* [Best practices](doc/best_practices.md)
7980
* [Tasks](doc/tasks.md)
8081
* [Transports](doc/transport.md)
8182
* [Commands](doc/command.md)

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@
107107
"phpstan/phpstan-doctrine": "^0.12.19",
108108
"phpstan/phpstan-phpunit": "^0.12",
109109
"phpstan/phpstan-symfony": "^0.12.19",
110+
"psalm/plugin-symfony": "^2.1",
110111
"phpunit/phpunit": "^9.5",
111112
"psalm/plugin-phpunit": "^0.15",
112113
"psr/cache": "^1.0",

doc/best_practices.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Best practices
2+
3+
- [Transports](#Transports)
4+
- [External ressources](#external-ressources)
5+
6+
## Transports
7+
8+
When using transports that rely on network calls, you must keep in mind that these transports
9+
can fail to retrieve/create and so on, it could be a good idea to use the fail over or round robin
10+
transport to prevent any errors:
11+
12+
```yaml
13+
scheduler_bundle:
14+
transport:
15+
dsn: 'failover://(doctrine://... || fs://last_in_first_out)'
16+
```
17+
18+
## External ressources
19+
20+
Consider exploring this [article](https://www.endpoint.com/blog/2008/12/08/best-practices-for-cron)
21+
to have a better idea of general approaches related to repetitive tasks.

doc/scheduler.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,26 @@ final class Foo
8282
$scheduler->yieldTask('foo', true);
8383
}
8484
}
85-
```
85+
```
86+
87+
### Pausing task
88+
89+
_Introduced in `0.3`_
90+
91+
Pausing a task using the asynchronous approach requires to use the method second argument:
92+
93+
```php
94+
<?php
95+
96+
declare(strict_types=1);
97+
98+
use SchedulerBundle\SchedulerInterface;
99+
100+
final class Foo
101+
{
102+
public function __invoke(SchedulerInterface $scheduler): void
103+
{
104+
$scheduler->pause('foo', true);
105+
}
106+
}
107+
```

doc/tasks.md

Lines changed: 80 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,21 @@
22

33
This bundle provides multiple type of tasks:
44

5-
- [ShellTask](tasks.md#ShellTask)
6-
- [CommandTask](tasks.md#CommandTask)
7-
- [ChainedTask](tasks.md#ChainedTask)
8-
- [CallbackTask](tasks.md#CallbackTask)
5+
- [ShellTask](#ShellTask)
6+
- [CommandTask](#CommandTask)
7+
- [ChainedTask](#ChainedTask)
8+
- [CallbackTask](#CallbackTask)
99
- HttpTask
1010
- MessengerTask
11-
- [NotificationTask](tasks.md#NotificationTask)
12-
- [NullTask](tasks.md#NullTask)
11+
- [NotificationTask](#NotificationTask)
12+
- [NullTask](#NullTask)
1313

1414
## Extra
1515

16-
- [Task callbacks](tasks.md#Callbacks)
17-
- [Task notifications](tasks.md#Notifications)
18-
- [Options](tasks.md#Options)
16+
- [Task callbacks](#Callbacks)
17+
- [Task notifications](#Notifications)
18+
- [Options](#Options)
19+
- [Fluent Expression](#fluent-expressions)
1920

2021
## ShellTask
2122

@@ -180,3 +181,73 @@ Each task can define a set of notification:
180181
## Options
181182

182183
Each task has its own set of options, the full list is documented in [AbstractTask](../src/Task/AbstractTask.php).
184+
185+
## Fluent expressions
186+
187+
_Introduced in `0.3`_
188+
189+
This bundle supports defining tasks expression via basic cron syntax:
190+
191+
```bash
192+
* * * * *
193+
```
194+
195+
Even if this approach is mostly recommended, you may need to use a more "user-friendly" syntax, to do so,
196+
this bundle allows you to use "fluent" expressions thanks to [strtotime](https://www.php.net/manual/fr/function.strtotime) and "computed" expressions:
197+
198+
### Strtotime
199+
200+
Scheduling a task with a "fluent" expression is as easy as it sounds:
201+
202+
```yaml
203+
scheduler_bundle:
204+
# ...
205+
tasks:
206+
foo:
207+
type: 'shell'
208+
command: ['ls', '-al']
209+
expression: 'next monday 10:00'
210+
```
211+
212+
Every expression supported by [strtotime](https://www.php.net/manual/fr/function.strtotime) is allowed.
213+
214+
_Note: Keep in mind that using a fluent expression does not lock the amount of execution of the task,
215+
if it should only run once, you must consider using the `single_run` option._
216+
217+
_Note: If you need to generate the expression thanks to a specific timezone, the `timezone` option can be used:_
218+
219+
```yaml
220+
scheduler_bundle:
221+
# ...
222+
tasks:
223+
foo:
224+
type: 'shell'
225+
command: ['ls', '-al']
226+
expression: 'next monday 10:00'
227+
timezone: 'Europe/Paris'
228+
```
229+
230+
*The default value is `UTC`*
231+
232+
### Computed expressions
233+
234+
A "computed" expression is a special expression that use `#` for specific parts of the expression:
235+
236+
```yaml
237+
scheduler_bundle:
238+
# ...
239+
tasks:
240+
foo:
241+
type: 'shell'
242+
command: ['ls', '-al']
243+
expression: '# * * * *'
244+
```
245+
246+
The final expression will contain an integer 0 and 59 in the minute field of the expression
247+
as described in the [man page](https://crontab.guru/crontab.5.html).
248+
249+
_Note: `#` can be used in multiple parts of the expression at the same time._
250+
251+
### Notices
252+
253+
Both computed and fluent expressions cannot be used *outside* of the configuration definition.

psalm.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@
1414
</projectFiles>
1515
<plugins>
1616
<pluginClass class="Psalm\PhpUnitPlugin\Plugin"/>
17-
</plugins>
17+
<pluginClass class="Psalm\SymfonyPsalmPlugin\Plugin"/></plugins>
1818
</psalm>

src/Command/ConsumeTasksCommand.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ final class ConsumeTasksCommand extends Command
3636
private WorkerInterface $worker;
3737

3838
/**
39-
* @var string|mixed
39+
* @var string|null
4040
*/
4141
protected static $defaultName = 'scheduler:consume';
4242

@@ -162,6 +162,10 @@ private function registerOutputSubscriber(SymfonyStyle $style): void
162162
{
163163
$this->eventDispatcher->addListener(TaskExecutedEvent::class, function (TaskExecutedEvent $event) use ($style): void {
164164
$output = $event->getOutput();
165+
if (null === $output) {
166+
return;
167+
}
168+
165169
if (null === $output->getOutput()) {
166170
return;
167171
}

src/Command/ListFailedTasksCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ final class ListFailedTasksCommand extends Command
2424
private WorkerInterface $worker;
2525

2626
/**
27-
* @var string
27+
* @var string|null
2828
*/
2929
protected static $defaultName = 'scheduler:list:failed';
3030

src/Command/ListTasksCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ final class ListTasksCommand extends Command
2828
private SchedulerInterface $scheduler;
2929

3030
/**
31-
* @var string
31+
* @var string|null
3232
*/
3333
protected static $defaultName = 'scheduler:list';
3434

0 commit comments

Comments
 (0)