Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitfd2967e

Browse files
committed
Add AsCronTask & AsPeriodicTask attributes
1 parent73a6b4b commitfd2967e

File tree

10 files changed

+218
-1
lines changed

10 files changed

+218
-1
lines changed

‎src/Symfony/Bundle/FrameworkBundle/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',

‎src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,9 @@
151151
useSymfony\Component\RemoteEvent\RemoteEvent;
152152
useSymfony\Component\Routing\Loader\AnnotationClassLoader;
153153
useSymfony\Component\Routing\Loader\Psr4DirectoryLoader;
154+
useSymfony\Component\Scheduler\Attribute\AsCronTask;
154155
useSymfony\Component\Scheduler\Attribute\AsSchedule;
156+
useSymfony\Component\Scheduler\Attribute\AsPeriodicTask;
155157
useSymfony\Component\Scheduler\Messenger\SchedulerTransportFactory;
156158
useSymfony\Component\Security\Core\AuthenticationEvents;
157159
useSymfony\Component\Security\Core\Exception\AuthenticationException;
@@ -716,6 +718,28 @@ public function load(array $configs, ContainerBuilder $container)
716718
$container->registerAttributeForAutoconfiguration(AsSchedule::class,staticfunction (ChildDefinition$definition,AsSchedule$attribute):void {
717719
$definition->addTag('scheduler.schedule_provider', ['name' =>$attribute->name]);
718720
});
721+
foreach ([AsPeriodicTask::class, AsCronTask::class]as$taskAttributeClass) {
722+
$container->registerAttributeForAutoconfiguration(
723+
$taskAttributeClass,
724+
staticfunction (ChildDefinition$definition,AsPeriodicTask|AsCronTask$attribute,\ReflectionClass|\ReflectionMethod$reflector):void {
725+
$tagAttributes =get_object_vars($attribute) + [
726+
'trigger' =>match (get_class($attribute)) {
727+
AsPeriodicTask::class =>'every',
728+
AsCronTask::class =>'cron',
729+
}
730+
];
731+
if ($reflectorinstanceof \ReflectionMethod) {
732+
if (isset($tagAttributes['method'])) {
733+
thrownewLogicException(
734+
sprintf('AsPeriodicTask attribute cannot declare a method on "%s::%s()".',$reflector->class,$reflector->name)
735+
);
736+
}
737+
$tagAttributes['method'] =$reflector->getName();
738+
}
739+
$definition->addTag('scheduler.task',$tagAttributes);
740+
}
741+
);
742+
}
719743

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

‎src/Symfony/Bundle/FrameworkBundle/Resources/config/scheduler.php

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

1414
useSymfony\Component\Scheduler\Messenger\SchedulerTransportFactory;
15+
useSymfony\Component\Scheduler\Messenger\ServiceCallMessageHandler;
1516

1617
returnstaticfunction (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+
namespaceSymfony\Bundle\FrameworkBundle\Tests\Fixtures\Messenger;
4+
5+
useSymfony\Component\Scheduler\Attribute\AsCronTask;
6+
useSymfony\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+
publicstaticarray$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+
publicfunctionattributesOnMethod(string$a,int$b):void
19+
{
20+
self::$calls[__FUNCTION__][] = [$a,$b];
21+
}
22+
23+
publicfunction__call(string$name,array$arguments)
24+
{
25+
self::$calls[$name][] =$arguments;
26+
}
27+
}

‎src/Symfony/Bundle/FrameworkBundle/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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespaceSymfony\Component\Scheduler\Attribute;
4+
5+
/**
6+
* A marker to call a service method from scheduler
7+
*
8+
* @author valtzu <valtzu@gmail.com>
9+
*/
10+
#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
11+
class AsCronTask
12+
{
13+
publicfunction__construct(
14+
publicreadonlystring$expression,
15+
publicreadonly ?string$timezone =null,
16+
publicreadonly ?int$jitter =null,
17+
publicreadonlyarray$arguments = [],
18+
publicreadonlystring$schedule ='default',
19+
publicreadonly ?string$method =null,
20+
) {
21+
}
22+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespaceSymfony\Component\Scheduler\Attribute;
13+
14+
/**
15+
* A marker to call a service method from scheduler
16+
*
17+
* @author valtzu <valtzu@gmail.com>
18+
*/
19+
#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
20+
class AsPeriodicTask
21+
{
22+
publicfunction__construct(
23+
publicreadonlystring|int$frequency,
24+
publicreadonly ?string$from =null,
25+
publicreadonly ?string$until =null,
26+
publicreadonly ?int$jitter =null,
27+
publicreadonlyarray$arguments = [],
28+
publicreadonlystring$schedule ='default',
29+
publicreadonly ?string$method =null,
30+
) {
31+
}
32+
}

‎src/Symfony/Component/Scheduler/DependencyInjection/AddScheduleMessengerPass.php

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,12 @@
1414
useSymfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
1515
useSymfony\Component\DependencyInjection\ContainerBuilder;
1616
useSymfony\Component\DependencyInjection\Definition;
17+
useSymfony\Component\DependencyInjection\Exception\InvalidArgumentException;
1718
useSymfony\Component\DependencyInjection\Reference;
1819
useSymfony\Component\Messenger\Transport\TransportInterface;
20+
useSymfony\Component\Scheduler\Messenger\ServiceCallMessage;
21+
useSymfony\Component\Scheduler\RecurringMessage;
22+
useSymfony\Component\Scheduler\Schedule;
1923

2024
/**
2125
* @internal
@@ -29,8 +33,45 @@ public function process(ContainerBuilder $container): void
2933
$receivers[$tags[0]['alias']] =true;
3034
}
3135

32-
foreach ($container->findTaggedServiceIds('scheduler.schedule_provider')as$tags) {
36+
$scheduleProviders = [];
37+
foreach ($container->findTaggedServiceIds('scheduler.schedule_provider')as$serviceId =>$tags) {
3338
$name =$tags[0]['name'];
39+
$scheduleProviders[$name] =$container->getDefinition($serviceId);
40+
}
41+
42+
foreach ($container->findTaggedServiceIds('scheduler.task')as$serviceId =>$tags) {
43+
foreach ($tagsas$tagAttributes) {
44+
$scheduleName =$tagAttributes['schedule'] ??'default';
45+
$scheduleProviders[$scheduleName] ??=$container->setDefinition("scheduler.provider.$scheduleName",newDefinition(Schedule::class))
46+
->addTag('scheduler.schedule_provider', ['name' =>$scheduleName]);
47+
48+
$taskArguments = [
49+
'$message' =>newDefinition(ServiceCallMessage::class, [$serviceId,$tagAttributes['method'] ??'__invoke',$tagAttributes['arguments'] ?? []])
50+
] +array_filter(match ($tagAttributes['trigger'] ??thrownewInvalidArgumentException("Tag 'scheduler.task' is missing attribute 'trigger' on service$serviceId")) {
51+
'every' => [
52+
'$frequency' =>$tagAttributes['frequency'] ??thrownewInvalidArgumentException("Tag 'scheduler.task' is missing attribute 'frequency' on service$serviceId"),
53+
'$from' =>$tagAttributes['from'] ??null,
54+
'$until' =>$tagAttributes['until'] ??null,
55+
],
56+
'cron' => [
57+
'$expression' =>$tagAttributes['expression'] ??thrownewInvalidArgumentException("Tag 'scheduler.task' is missing attribute 'expression' on service$serviceId"),
58+
'$timezone' =>$tagAttributes['timezone'] ??null,
59+
],
60+
},fn ($value) => !is_null($value));
61+
62+
$taskDefinition = (newDefinition(RecurringMessage::class))
63+
->setFactory([RecurringMessage::class,$tagAttributes['trigger']])
64+
->setArguments($taskArguments);
65+
66+
if ($tagAttributes['jitter'] ??false) {
67+
$taskDefinition->addMethodCall('withJitter', [$tagAttributes['jitter']],true);
68+
}
69+
70+
$scheduleProviders[$scheduleName]->addMethodCall('add', [$taskDefinition]);
71+
}
72+
}
73+
74+
foreach (array_keys($scheduleProviders)as$name) {
3475
$transportName ='scheduler_'.$name;
3576

3677
// allows to override the default transport registration
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
namespaceSymfony\Component\Scheduler\Messenger;
4+
5+
6+
/**
7+
* Represents a service call
8+
*
9+
* @author valtzu <valtzu@gmail.com>
10+
*/
11+
class ServiceCallMessageimplements \Stringable
12+
{
13+
publicfunction__construct(
14+
privatereadonlystring$serviceId,
15+
privatereadonlystring$method ='__invoke',
16+
privatereadonlyarray$arguments = [],
17+
) {
18+
}
19+
20+
publicfunctiongetServiceId():string
21+
{
22+
return$this->serviceId;
23+
}
24+
25+
publicfunctiongetMethod():string
26+
{
27+
return$this->method;
28+
}
29+
30+
publicfunctiongetArguments():array
31+
{
32+
return$this->arguments;
33+
}
34+
35+
publicfunction__toString():string
36+
{
37+
returnsprintf("ServiceCallMessage<%s>","@$this->serviceId" . ($this->method !=='__invoke' ?"::$this->method" :''));
38+
}
39+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespaceSymfony\Component\Scheduler\Messenger;
4+
5+
usePsr\Container\ContainerInterface;
6+
7+
/**
8+
* Handler to call any service
9+
*
10+
* @author valtzu <valtzu@gmail.com>
11+
*/
12+
class ServiceCallMessageHandler
13+
{
14+
publicfunction__construct(privatereadonlyContainerInterface$serviceLocator)
15+
{
16+
}
17+
18+
publicfunction__invoke(ServiceCallMessage$message):void
19+
{
20+
$this->serviceLocator->get($message->getServiceId())->{$message->getMethod()}(...$message->getArguments());
21+
}
22+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp