Pour automatiser certaines tâches récurrentes liées à mes applications, j’utilise actuellement les cron jobs de Linux. Ces derniers permettent de lancer des commandes Symfony à des horaires prédéfinis.
Cela fonctionne évidemment très bien (cron existe depuis presque aussi longtemps que l’informatique !). 😊
Cependant, cette méthode présente quelques inconvénients :
- Lorsque l’on migre une application vers un nouveau serveur, il faut penser à recréer tous les cron jobs, avec les bonnes commandes et les bons horaires.
- Lors d’un changement de version de PHP, il faut mettre à jour le binaire PHP dans chaque cron.
- Si vous n’êtes pas administrateur du serveur, vous ne pouvez pas vérifier facilement si le cron est bien configuré, s’il s’exécute correctement, ou à quel moment.
Pourquoi embarquer les cron jobs dans l’application ?
Ces limitations m’ont amené à réfléchir à une alternative : intégrer les cron jobs directement dans l’application. Cela apporte plusieurs avantages :
- Portabilité : plus besoin de reconfigurer manuellement les tâches lors d’un changement de serveur.
- Flexibilité : possibilité de définir des conditions dynamiques pour le déclenchement des tâches (par exemple, en fonction de l’état d’une entité).
Et comme vous allez le voir, c’est assez simple à mettre en place, surtout en utilisant le maker-bundle de Symfony.
Introduction au composant Scheduler de Symfony
Le composant Scheduler repose sur Messenger pour l’exécution des tâches, mais utilise un transport spécifique : SchedulerTransport
.
Installation des dépendances
Pour commencer, installons les composants nécessaires :
composer require symfony/scheduler
composer require symfony/messenger
composer require symfony/maker-bundle --dev
Création de notre tâche (Message)
Nous allons créer une tâche simple, qui se contentera d’afficher l’heure actuelle dans la console. Cela nous permettra de vérifier facilement si elle est bien exécutée à l’intervalle prévu.
Exécutez la commande suivante pour générer une nouvelle classe de message :
bin/console make:message
Cela crée deux fichiers :
- Le message : il contient les propriétés et les méthodes liées à la tâche.
- Le handler : il décrit l’action à exécuter pour ce message.
Exemple minimal de message
Voici un exemple de classe de message vide :
namespace App\Message;
final class PocMessage
{
public function __construct()
{
// Pas de propriétés pour cet exemple minimal
}
}
Exemple de handler
Le handler associé affichera simplement la date et l’heure actuelles :
namespace App\MessageHandler;
use App\Message\PocMessage;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
#[AsMessageHandler]
final class PocMessageHandler
{
public function __invoke(PocMessage $message): void
{
echo date('Y-m-d H:i:s') . PHP_EOL;
}
}
Configuration du Scheduler
Ensuite, créons un scheduler à l’aide du maker :
bin/console make:schedule
Cela génère une classe qui définira la planification des tâches. Voici un exemple de configuration :
namespace App\Schedule;
use App\Message\PocMessage;
use Symfony\Component\Scheduler\Attribute\AsSchedule;
use Symfony\Component\Scheduler\RecurringMessage;
use Symfony\Component\Scheduler\Schedule;
use Symfony\Component\Scheduler\ScheduleProviderInterface;
#[AsSchedule('poc')]
final class MainSchedule implements ScheduleProviderInterface
{
public function getSchedule(): Schedule
{
return (new Schedule())
->add(
RecurringMessage::every('1 minute', new PocMessage())
);
}
}
Points clés
- La méthode
RecurringMessage::every()
permet de définir l’intervalle d’exécution. Ici, nous avons choisi une tâche qui s’exécute toutes les minutes.
Exécution du scheduler
Pour démarrer le scheduler, utilisez la commande suivante :
bin/console messenger:consume scheduler_poc
Si tout fonctionne correctement, vous devriez voir l’heure s’afficher dans la console toutes les minutes :
2024-11-24 19:53:22
2024-11-24 19:54:22
2024-11-24 19:55:22
Conclusion
Le composant Scheduler de Symfony offre une solution élégante pour gérer vos tâches récurrentes directement depuis votre application. Il réduit la dépendance aux configurations système et améliore la portabilité et la flexibilité.
N’hésitez pas à l’expérimenter et à l’adapter à vos besoins spécifiques. 🚀