Skip to content

Commit 13b0060

Browse files
valtzufabpot
authored andcommitted
[Messenger][Scheduler] Add AsCronTask & AsPeriodicTask attributes
1 parent 705ab0c commit 13b0060

File tree

5 files changed

+59
-0
lines changed

5 files changed

+59
-0
lines changed

DependencyInjection/Compiler/UnusedTagsPass.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ class UnusedTagsPass implements CompilerPassInterface
8484
'routing.loader',
8585
'routing.route_loader',
8686
'scheduler.schedule_provider',
87+
'scheduler.task',
8788
'security.authenticator.login_linker',
8889
'security.expression_language_provider',
8990
'security.remember_me_handler',

DependencyInjection/FrameworkExtension.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@
145145
use Symfony\Component\RemoteEvent\Attribute\AsRemoteEventConsumer;
146146
use Symfony\Component\RemoteEvent\RemoteEvent;
147147
use Symfony\Component\Routing\Loader\AnnotationClassLoader;
148+
use Symfony\Component\Scheduler\Attribute\AsCronTask;
149+
use Symfony\Component\Scheduler\Attribute\AsPeriodicTask;
148150
use Symfony\Component\Scheduler\Attribute\AsSchedule;
149151
use Symfony\Component\Scheduler\Messenger\SchedulerTransportFactory;
150152
use Symfony\Component\Security\Core\AuthenticationEvents;
@@ -701,6 +703,26 @@ public function load(array $configs, ContainerBuilder $container)
701703
$container->registerAttributeForAutoconfiguration(AsSchedule::class, static function (ChildDefinition $definition, AsSchedule $attribute): void {
702704
$definition->addTag('scheduler.schedule_provider', ['name' => $attribute->name]);
703705
});
706+
foreach ([AsPeriodicTask::class, AsCronTask::class] as $taskAttributeClass) {
707+
$container->registerAttributeForAutoconfiguration(
708+
$taskAttributeClass,
709+
static function (ChildDefinition $definition, AsPeriodicTask|AsCronTask $attribute, \ReflectionClass|\ReflectionMethod $reflector): void {
710+
$tagAttributes = get_object_vars($attribute) + [
711+
'trigger' => match ($attribute::class) {
712+
AsPeriodicTask::class => 'every',
713+
AsCronTask::class => 'cron',
714+
},
715+
];
716+
if ($reflector instanceof \ReflectionMethod) {
717+
if (isset($tagAttributes['method'])) {
718+
throw new LogicException(sprintf('%s attribute cannot declare a method on "%s::%s()".', $attribute::class, $reflector->class, $reflector->name));
719+
}
720+
$tagAttributes['method'] = $reflector->getName();
721+
}
722+
$definition->addTag('scheduler.task', $tagAttributes);
723+
}
724+
);
725+
}
704726

705727
if (!$container->getParameter('kernel.debug')) {
706728
// remove tagged iterator argument for resource checkers

Resources/config/scheduler.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,15 @@
1212
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
1313

1414
use Symfony\Component\Scheduler\Messenger\SchedulerTransportFactory;
15+
use Symfony\Component\Scheduler\Messenger\ServiceCallMessageHandler;
1516

1617
return static function (ContainerConfigurator $container) {
1718
$container->services()
19+
->set('scheduler.messenger.service_call_message_handler', ServiceCallMessageHandler::class)
20+
->args([
21+
tagged_locator('scheduler.task'),
22+
])
23+
->tag('messenger.message_handler')
1824
->set('scheduler.messenger_transport_factory', SchedulerTransportFactory::class)
1925
->args([
2026
tagged_locator('scheduler.schedule_provider', 'name'),
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
namespace Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Messenger;
4+
5+
use Symfony\Component\Scheduler\Attribute\AsCronTask;
6+
use Symfony\Component\Scheduler\Attribute\AsPeriodicTask;
7+
8+
#[AsCronTask(expression: '* * * * *', arguments: [1], schedule: 'dummy')]
9+
#[AsCronTask(expression: '0 * * * *', timezone: 'Europe/Berlin', arguments: ['2'], schedule: 'dummy', method: 'method2')]
10+
#[AsPeriodicTask(frequency: 5, arguments: [3], schedule: 'dummy')]
11+
#[AsPeriodicTask(frequency: 'every day', from: '00:00:00', jitter: 60, arguments: ['4'], schedule: 'dummy', method: 'method4')]
12+
class DummyTask
13+
{
14+
public static array $calls = [];
15+
16+
#[AsPeriodicTask(frequency: 'every hour', from: '09:00:00', until: '17:00:00', arguments: ['b' => 6, 'a' => '5'], schedule: 'dummy')]
17+
#[AsCronTask(expression: '0 0 * * *', arguments: ['7', 8], schedule: 'dummy')]
18+
public function attributesOnMethod(string $a, int $b): void
19+
{
20+
self::$calls[__FUNCTION__][] = [$a, $b];
21+
}
22+
23+
public function __call(string $name, array $arguments)
24+
{
25+
self::$calls[$name][] = $arguments;
26+
}
27+
}

Tests/Functional/app/Scheduler/config.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ services:
1010
Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Messenger\DummySchedule:
1111
autoconfigure: true
1212

13+
Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Messenger\DummyTask:
14+
autoconfigure: true
15+
1316
clock:
1417
synthetic: true
1518

0 commit comments

Comments
 (0)