// composer.json
{
"require": {
"php": ">=8.3",
"ext-ctype": "*",
"ext-iconv": "*",
"babdev/pagerfanta-bundle": "^4.0", // v4.4.0
"doctrine/doctrine-bundle": "^2.7", // 2.11.1
"doctrine/doctrine-migrations-bundle": "^3.2", // 3.3.0
"doctrine/orm": "^2.12", // 2.17.3
"knplabs/knp-time-bundle": "^2.2", // v2.2.0
"pagerfanta/doctrine-orm-adapter": "^4.0", // v4.2.0
"pagerfanta/twig": "^4.0", // v4.2.0
"stof/doctrine-extensions-bundle": "^1.7", // v1.10.1
"symfony/asset": "7.0.*", // v7.0.0
"symfony/asset-mapper": "7.0.*", // v7.0.2
"symfony/console": "7.0.*", // v7.0.2
"symfony/dotenv": "7.0.*", // v7.0.2
"symfony/flex": "^2", // v2.4.3
"symfony/framework-bundle": "7.0.*", // v7.0.2
"symfony/http-client": "7.0.*", // v7.0.2
"symfony/messenger": "7.0.*", // v7.0.1
"symfony/monolog-bundle": "^3.0", // v3.10.0
"symfony/runtime": "7.0.*", // v7.0.0
"symfony/scheduler": "7.0.*", // v7.0.0
"symfony/twig-bundle": "7.0.*", // v7.0.0
"symfony/ux-turbo": "^2.0", // v2.13.2
"symfony/yaml": "7.0.*", // v7.0.0
"twig/extra-bundle": "^2.12|^3.0", // v3.8.0
"twig/twig": "^2.12|^3.0" // v3.8.0
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.4", // 3.5.1
"symfony/debug-bundle": "7.0.*", // v7.0.0
"symfony/maker-bundle": "^1.41", // v1.52.0
"symfony/stopwatch": "7.0.*", // v7.0.0
"symfony/web-profiler-bundle": "7.0.*", // v7.0.2
"zenstruck/foundry": "^1.21" // v1.36.1
}
}
18 Comments
I have a collection of Symfony console commands that I would like to run using the scheduler at different times but I would like to be able to manage these commands and their CRON expression from the database.
So I have created a `ScheduledCommand ' entity with properties such as
app:send-api-create,*/5 * * * *, andI manage these ScheduledCommands objects from the UI.
Then I have the Schedule.php, what would be the best way to update the scheduler in real-time, for instance, if the command is changed (arguments/options updated) or the CRON expression is altered in the database, it also reflects in the scheduler and consumer picks up the new changes in real time?
Currently, if I have the consumer running in the terminal and any command is changed from the UI, it won't be reflected in the consumer.
bin/console messenger:consume scheduler_default -vvHey @GhazanfarMir
I think you can do it by implementing a custom scheduler provider that reads your database and set up the schedule. Something like this
Then, you can start the consumer worker to only dispatch a low amount of messages so it restarts often and it catch up with the changes.
Also, here's info on how to modify scheduled messages in real time: https://symfony.com/doc/current/scheduler.html#modifying-scheduled-messages-in-real-time
Hope it helps. Cheers!
Does anybody know how to deploy a symfony app with scheduler on azure? I have an ASP with a PHP webapp on azure. I think best practice would be to use a docker image instead?
If so, which docker image would you recommend for production?
Hey Mike-Profile,
Well, probably Azure docs will suggest some? Maybe they have their own Docker images, not sure. Can't really suggest a good one as we don't use Docker, but I think if there's no any Azure-specific images, you can always go with the official Docker images for the technologies you're using, I bet that's a good fallback option.
About specific deploy, I haven't used Azure personally, but usually you can deploy everything with Ansible and Ansistrano. Take a look at the Ansistrano course we have on SymfonyCasts: https://symfonycasts.com/screencast/ansistrano
I hope that helps!
Cheers!
Is this correct?
"Previously, Symfony had separate commands for processing scheduled tasks and regular messages:
These processes operated independently, requiring separate execution to handle both scheduled and regular messages. 
In Symfony 7.2, the Scheduler has been fully integrated into the Messenger system. Scheduled tasks are now treated as Messenger messages, eliminating the need for a separate scheduler:consume command. Instead, the messenger:consume command processes both regular and scheduled messages.
Therefore, to process scheduled tasks in Symfony 7.2, you should use the messenger:consume command with the appropriate transport:
php bin/console messenger:consume async -vv
This command will handle both regular and scheduled messages, streamlining the message processing workflow."
Hey @Mike-Profile!
No, I don't believe there was ever a
scheduler:consume. Even when the Scheduler was introduced in 6.3, it wasmessenger:consume.Where did you find that note?
--Kevin
Thank you! It was my mistake, a personal readme note in combination with AI hallucination.
Hah, no problem. I suspected AI hallucination!
I use to clear cache every time I push changes. It affects the scheduler cache? clear cache with cache:clear after pushing changes is not a good practice?
Hey @Adrian_Ntss!
You have configured a stateful schedule? You'll need to use a cache that doesn't get cleared when you deploy (or run
cache:clearon production). This could be something like Redis or even a different filesystem cache in a different directory (that's kept between deploys).In the documentation they use "(new Schedule())->with()", but here you are using "(new Schedule())->add()".
Why?
Hey @Nick-F! Good catch!
These methods are almost the same but have one subtle difference, and this only applies under certain circumstances.
with()can be used at runtime to add additional tasks dynamically (without restarting the schedule).add()ensures the schedule is reset before adding.If using the Scheduler the standard way, and how we use it in this chapter, it doesn't matter which method you use. The schedule is built when it's first started so it's always reset.
If you require adding tasks at runtime, a more advanced usage, you'd use
with().Hope this helps!
Hello,
I don't get one thing...
I've created a scheduler, which executes every 7 seconds (I don't add any lock, as you can see):
This scheduler sometimes runs very hard tasks (> 7 seconds), and it looks like next scheduler tick isn't triggered until previous tick isn't finished. If some scheduler tick executes, let's say, 2 minutes, there is no next scheduler ticks (every 7 seconds) during those 2 minutes.
I expected, that scheduler starts some task and handles it in background, so "7 seconds" works like a clock (like unix cron). But it looks like some blocking process is present, and next scheduler ticks "waiting" for previous task finishing.
Am I right or I miss something?
PS. Just in case - here are my scheduler process settings (in supervisor conf):
Hey @BooleanType!
Yes, when a scheduled message is dispatched, it blocks the process (preventing schedule ticks). As you've noted, this is unlike a standard unix cron job. From what you describe, the schedule likely never catches up.
I think your best bet would be to have another worker running a standard
messenger:consumeon a non-schedule transport (likeasync). Then, when creating the schedule, wrap your message withRedispatchMessage:This will have the schedule only dispatch another message, freeing it up to be available for the next tick.
You can find some documentation on this at the end of this section.
Let me know if you have any luck with this!
Thank you for such a detailed answer, now it’s clearer to me!
For now, I gave preference to the good old cron, leaving the scheduler “until better times” :)
Is it good to use this component for database and/or images upload daily backups?
Hey @Kirill
I've not used it for tasks like that but I'd say yes, it should work, the only issue I can think of is if the backup takes too much time to complete, it may delay other tasks to execute. If that's the case you could configure it to run at midnight (or at your lowest traffic hours), or set up a dedicated worker for this Schedule
Cheers!
Thank you
"Houston: no signs of life"
Start the conversation!