8000 feature #63135 [Scheduler] Add option to order recurring messages by … · symfony/symfony@9f07b1b · GitHub
[go: up one dir, main page]

Skip to content

Commit 9f07b1b

Browse files
feature #63135 [Scheduler] Add option to order recurring messages by next run date in debug command (yoye)
This PR was merged into the 8.1 branch. Discussion ---------- [Scheduler] Add option to order recurring messages by next run date in debug command | Q | A | ------------- | --- | Branch? | 8.1 | Bug fix? | no | New feature? | no | Deprecations? | no | Issues | | License | MIT This PR adds a `--sort` option to `debug:scheduler` to sort recurring messages by their next run date. This can be especially helpful when working with a large number of scheduled tasks, as it makes overlapping or closely scheduled executions easier to spot. ### Before ``` Scheduler ========= default ------- --------------- --------------------------------------------------------------------- --------------------------------- Trigger Provider Next Run --------------- --------------------------------------------------------------------- --------------------------------- 30 4 * * 1 Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Mon, 26 Jan 2026 04:30:00 +0000 20 * * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Tue, 20 Jan 2026 15:20:00 +0000 30 1 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 01:30:00 +0000 0 3 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 03:00:00 +0000 30 */6 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Tue, 20 Jan 2026 18:30:00 +0000 */5 * * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Tue, 20 Jan 2026 14:35:00 +0000 */5 * * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Tue, 20 Jan 2026 14:35:00 +0000 0 10 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 10:00:00 +0000 0 4 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 04:00:00 +000 10000 0 0 * * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Tue, 20 Jan 2026 15:00:00 +0000 */5 * * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Tue, 20 Jan 2026 14:35:00 +0000 0 4 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 04:00:00 +0000 0 8 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 08:00:00 +0000 15,45 * * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Tue, 20 Jan 2026 14:45:00 +0000 0 7 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 07:00:00 +0000 0 * * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Tue, 20 Jan 2026 15:00:00 +0000 0 */1 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Tue, 20 Jan 2026 15:00:00 +0000 0 4 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 04:00:00 +0000 */5 * * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Tue, 20 Jan 2026 14:35:00 +0000 */5 * * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Tue, 20 Jan 2026 14:35:00 +0000 0 4 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 04:00:00 +0000 */5 * * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Tue, 20 Jan 2026 14:35:00 +0000 0 5 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 05:00:00 +0000 15 * * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Tue, 20 Jan 2026 15:15:00 +0000 0 9 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 09:00:00 +0000 0 14 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 14:00:00 +0000 30 9 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 09:30:00 +0000 0 7 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 07:00:00 +0000 5 6 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 06:05:00 +0000 0 2 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 02:00:00 +0000 */5 * * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Tue, 20 Jan 2026 14:35:00 +0000 30 8 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 08:30:00 +0000 */15 * * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Tue, 20 Jan 2026 14:45:00 +0000 30 5 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 05:30:00 +0000 5 0 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 00:05:00 +0000 0 10 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 10:00:00 +0000 0 * * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Tue, 20 Jan 2026 15:00:00 +0000 30 4 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 04:30:00 +0000 --------------- --------------------------------------------------------------------- --------------------------------- ``` ### After ``` Scheduler ========= default ------- --------------- --------------------------------------------------------------------- --------------------------------- Trigger Provider Next Run --------------- --------------------------------------------------------------------- --------------------------------- */5 * * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Tue, 20 Jan 2026 14:35:00 +0000 */5 * * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Tue, 20 Jan 2026 14:35:00 +0000 */5 * * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Tue, 20 Jan 2026 14:35:00 +0000 */5 * * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Tue, 20 Jan 2026 14:35:00 +0000 */5 * * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Tue, 20 Jan 2026 14:35:00 +0000 */5 * * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Tue, 20 Jan 2026 14:35:00 +0000 */5 * * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Tue, 20 Jan 2026 14:35:00 +0000 15,45 * * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Tue, 20 Jan 2026 14:45:00 +0000 */15 * * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Tue, 20 Jan 2026 14:45:00 +0000 0 * * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Tue, 20 Jan 2026 15:00:00 +0000 0 * * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Tue, 20 Jan 2026 15:00:00 +0000 0 */1 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Tue, 20 Jan 2026 15:00:00 +0000 0 * * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Tue, 20 Jan 2026 15:00:00 +0000 15 * * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Tue, 20 Jan 2026 15:15:00 +0000 20 * * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Tue, 20 Jan 2026 15:20:00 +0000 30 */6 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Tue, 20 Jan 2026 18:30:00 +0000 5 0 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 00:05:00 +0000 30 1 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 01:30:00 +0000 0 2 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 02:00:00 +0000 0 3 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 03:00:00 +0000 0 4 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 04:00:00 +0000 0 4 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 04:00:00 +0000 0 4 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 04:00:00 +0000 0 4 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 04:00:00 +0000 30 4 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 04:30:00 +0000 0 5 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 05:00:00 +0000 30 5 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 05:30:00 +0000 5 6 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 06:05:00 +0000 0 7 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 07:00:00 +0000 0 7 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 07:00:00 +0000 0 8 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 08:00:00 +0000 30 8 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 08:30:00 +0000 0 9 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 09:00:00 +0000 30 9 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 09:30:00 +0000 0 10 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 10:00:00 +0000 0 10 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 10:00:00 +0000 0 14 * * * Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Wed, 21 Jan 2026 14:00:00 +0000 30 4 * * 1 Symfony\Component\Console\Messenger\RunCommandMessage (app:command) Mon, 26 Jan 2026 04:30:00 +0000 --------------- --------------------------------------------------------------------- --------------------------------- ``` Commits ------- 9077486 Add sorting option to DebugCommand for recurring messages
2 parents e8347b5 + 9077486 commit 9f07b1b

File tree

3 files changed

+89
-4
lines changed

3 files changed

+89
-4
lines changed

src/Symfony/Component/Scheduler/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
8.1
5+
---
6+
7+
* Add `--sort` option to `debug:command` to order recurring messages by next run date
8+
49
7.3
510
---
611

src/Symfony/Component/Scheduler/Command/DebugCommand.php

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ protected function configure(): void
4545
->addArgument('schedule', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, \sprintf('The schedule name (one of "%s")', implode('", "', $this->scheduleNames)), null, $this->scheduleNames)
4646
->addOption('date', null, InputOption::VALUE_REQUIRED, 'The date to use for the next run date', 'now')
4747
->addOption('all', null, InputOption::VALUE_NONE, 'Display all recurring messages, including the terminated ones')
48+
->addOption('sort', null, InputOption::VALUE_NONE, 'Sort recurring messages by next run date')
4849
->setHelp(<<<'EOF'
4950
The <info>%command.name%</info> lists schedules and their recurring messages:
5051
@@ -93,24 +94,31 @@ protected function execute(InputInterface $input, OutputInterface $output): int
9394

9495
continue;
9596
}
97+
98+
$recurringMessages = array_filter(array_map(self::renderRecurringMessage(...), $messages, array_fill(0, \count($messages), $date), array_fill(0, \count($messages), $input->getOption('all'))));
99+
100+
if ($input->getOption('sort')) {
101+
usort($recurringMessages, static fn (array $a, array $b): int => $a[2] <=> $b[2]);
102+
}
103+
96104
$io->table(
97105
['Trigger', 'Provider', 'Next Run'],
98-
array_filter(array_map(self::renderRecurringMessage(...), $messages, array_fill(0, \count($messages), $date), array_fill(0, \count($messages), $input->getOption('all')))),
106+
array_map(static fn (array $row): array => [$row[0], $row[1], $row[2]?->format('r') ?? '-'], $recurringMessages),
99107
);
100108
}
101109

102110
return 0;
103111
}
104112

105113
/**
106-
* @return array{0:string,1:string,2:string}|null
114+
* @return array{0:string,1:string,2:\DateTimeImmutable|null}|null
107115
*/
108116
private static function renderRecurringMessage(RecurringMessage $recurringMessage, \DateTimeImmutable $date, bool $all): ?array
109117
{
110118
$trigger = $recurringMessage->getTrigger();
111119

112-
$next = $trigger->getNextRunDate($date)?->format('r') ?? '-';
113-
if ('-' === $next && !$all) {
120+
$next = $trigger->getNextRunDate($date);
121+
if (null === $next && !$all) {
114122
return null;
115123
}
116124

src/Symfony/Component/Scheduler/Tests/Command/DebugCommandTest.php

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\Scheduler\Tests\Command;
1313

14+
use PHPUnit\Framework\Attributes\DataProvider;
1415
use PHPUnit\Framework\TestCase;
1516
use Symfony\Component\Console\Tester\CommandTester;
1617
use Symfony\Component\Scheduler\Command\DebugCommand;
@@ -150,4 +151,75 @@ public function testExecuteWithSchedule()
150151
" ------------------------------- ---------- --------------------------------- \n".
151152
"\n/", $tester->getDisplay(true));
152153
}
154+
155+
#[DataProvider('provideSorting')]
156+
public function testExecuteWithScheduleAndSortOption(bool $sorted, string $expected)
157+
{
158+
$schedule = new Schedule();
159+
$schedule
160+
->add(RecurringMessage::every('3 minutes', new \stdClass()))
161+
->add(RecurringMessage::every('1 minute', new \stdClass()))
162+
->add(RecurringMessage::every('2 minutes', new \stdClass()))
163+
;
164+
165+
$schedules = $this->createMock(ServiceProviderInterface::class);
166+
$schedules
167+
->expects($this->once())
168+
->method('getProvidedServices')
169+
->willReturn(['schedule_name' => $schedule])
170+
;
171+
$schedules
172+
->expects($this->once())
173+
->method('get')
174+
->willReturn($schedule)
175+
;
176+
177+
$command = new DebugCommand($schedules);
178+
$tester = new CommandTester($command);
179+
180+
$tester->execute(['--sort' => $sorted], ['decorated' => false]);
181+
182+
$this->assertMatchesRegularExpression($expected, $tester->getDisplay(true));
183+
}
184+
185+
public static function provideSorting(): iterable
186+
{
187+
yield 'Not sorted results' => [
188+
false,
189+
"/\n".
190+
"Scheduler\n".
191+
"=========\n".
192+
"\n".
193+
"schedule_name\n".
194+
"-------------\n".
195+
"\n".
196+
" ----------------- ---------- --------------------------------- \n".
197+
" Trigger Provider Next Run \n".
198+
" ----------------- ---------- --------------------------------- \n".
199+
" every 3 minutes stdClass \w{3}, \d{1,2} \w{3} \d{4} \d{2}:\d{2}:\d{2} (\+|-)\d{4} \n".
200+
" every 1 minute stdClass \w{3}, \d{1,2} \w{3} \d{4} \d{2}:\d{2}:\d{2} (\+|-)\d{4} \n".
201+
" every 2 minutes stdClass \w{3}, \d{1,2} \w{3} \d{4} \d{2}:\d{2}:\d{2} (\+|-)\d{4} \n".
202+
" ----------------- ---------- --------------------------------- \n".
203+
"\n/",
204+
];
205+
206+
yield 'Sorted results' => [
207+
true,
208+
"/\n".
209+
"Scheduler\n".
210+
"=========\n".
211+
83F4 "\n".
212+
"schedule_name\n".
213+
"-------------\n".
214+
"\n".
215+
" ----------------- ---------- --------------------------------- \n".
216+
" Trigger Provider Next Run \n".
217+
" ----------------- ---------- --------------------------------- \n".
218+
" every 1 minute stdClass \w{3}, \d{1,2} \w{3} \d{4} \d{2}:\d{2}:\d{2} (\+|-)\d{4} \n".
219+
" every 2 minutes stdClass \w{3}, \d{1,2} \w{3} \d{4} \d{2}:\d{2}:\d{2} (\+|-)\d{4} \n".
220+
" every 3 minutes stdClass \w{3}, \d{1,2} \w{3} \d{4} \d{2}:\d{2}:\d{2} (\+|-)\d{4} \n".
221+
" ----------------- ---------- --------------------------------- \n".
222+
"\n/",
223+
];
224+
}
153225
}

0 commit comments

Comments
 (0)
0