Découvrez nos offres pour faire du digital le levier de votre croissance !
Téléchargez le Guide Ultime de gestion de projet digitale pour vous aider à piloter vos transformations et faire les bons choix !
Les QueueWorkers sont une fonctionnalité arrivée avec Drupal 8 qui permet aux développeurs de créer des tâches asynchrones pour être exécutées en arrière-plan.
Elles sont utiles pour les tâches qui prennent un certain temps à être exécutées et qui ne doivent pas bloquer l'exécution du script principal. On peut utiliser les QueueWorkers pour des tâches telles que l'envoi de courriels, la mise à jour de données en arrière-plan, ou tout autre tâche qui ne doit pas être exécutée immédiatement. Ces tâches asynchrones sont mises en file d'attente et seront exécutées ultérieurement, de manière à ne pas bloquer l'exécution du script principal.
Avec la version 8 de Drupal (sortie en 2015), un nouveau concept central a vu le jour : les plugins. À ne pas confondre avec les modules. Les plugins semblent être destinés à remplacer les hooks historiques de Drupal.
Les plugins vous permettent d'ajouter des fonctionnalités aux éléments existants de votre site Web en créant des classes selon certaines normes. Ce système doit donc être utilisé pour les éléments récurrents, et peut donc continuer à être utilisé pour de nombreuses fonctionnalités, en utilisant des méthodes communes connues de tous les développeurs Drupal 8+, les différents éléments du système peuvent évoluer. Nous allons nous intéresser à un certain type de plugins, les Queue Workers.
Un QueueWorker est donc un certain type de plugin dont le rôle est simplement de traiter une liste d'éléments un par un. Une analogie pourrait être un tapis roulant sur une caisse dans un supermarché, le caissier passe en revue chaque article sur le tapis pour les scanner.
Les QueueWorkers sont pratiques dans Drupal pour regrouper de grandes opérations, comme l'envoi d'e-mails à plusieurs personnes. En utilisant un QueueWorker, vous essayez d'éviter de surcharger les ressources du serveur, ce qui pourrait entraîner la mise hors ligne du site jusqu'à ce que les ressources du serveur soient libérées.
Afin de réaliser cela, le QueueWorker utilise le cron API de Drupal, en remplacement du hook_cron_queue_info()
. Les QueueWorkers ne sont pas des cron, mais le cron peut les exécuter.
Pour créer un QueueWorker, il faut :
Une fois cela fait, le plugin sera trouvé et utilisable par Drupal (lorsqu'une mise en queue se fera sur l'ID du QueueWorker, il traitera les éléments).
/**
* Send renew mail to advert owner.
*
* @QueueWorker(
* id = "module_global_library_expiracy_warning",
* title = @Translation("Envoi mensuel à une bibliothèque de la liste de ses
* abonnements expirant ce mois"), cron = {"time" = 10}
* )
*/
class LibraryMonthlyExpiracyWarningQueueWorker extends QueueWorkerBase implements ContainerFactoryPluginInterface {
/**
* @var \Drupal\module_global\Manager\ExpiracyWarningManager
*/
protected $expiracyWarningManager;
/**
* {@inheritdoc}
*/
public function processItem($libraryNid) {
$this->expiracyWarningManager->sendMonthlyLibraryExpiracyWarning($libraryNid);
}
Pour notre exemple, nous mettons en place une fonctionnalité qui aura en charge de vérifier toutes les 30 minutes si la page d'accueil de plusieurs sites Web (projets), que nous avons définis, n'est pas hors service. C'est dans ce contexte que nous allons utiliser notre QueueWorker custom, car selon le nombre de projets cela peut affecter les performances de notre propre site.
Nous utilisons le hook_cron. Le hook est appelé par le système lorsque la tâche cron est exécutée, et il permet aux modules de planifier des tâches ou d'effectuer des actions pendant l'exécution du cron.
/**
* Implements hook_cron().
*/
function my_module_projects_monitoring_cron()
{
$currentTime = Drupal::time()->getRequestTime();
/** @var ProjectGateway $gateway */
$gateway = Drupal::service('Drupal\my_module_projects_monitoring\Gateway\ProjectGateway');
$last_run = Drupal::state()->get('my_module_projects_monitoring.last_run', 0);
// Check home page of site and return the status code every 30 min
$last_run_status_code = Drupal::state()->get('my_module_projects_monitoring.last_status_run', 0);
if(($currentTime - $last_run_status_code) > 1800) {
Drupal::logger('cron')->notice('Request homepage projects !');
Drupal::state()->set('my_module_projects_monitoring.last_status_run', $currentTime);
// Service Queue Worker
$queue = Drupal::service('Drupal\my_module_projects_monitoring\Plugin\QueueWorker\StatusCodeReportQueueWorker');
// Get all projects and call to queue worker
$projects = $gateway->getAllProjects();
foreach ($projects as $project) {
$queue->createItem($project->id());
}
}
}
namespace Drupal\my_module_projects_monitoring\Plugin\QueueWorker;
use Drupal;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Queue\QueueWorkerBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Plugin implementation of the status_code_report queueworker.
*
* @QueueWorker (
* id = "status_code_report",
* title = @Translation("projects status code data"),
* cron = {"time" = 50}
* )
*/
class StatusCodeReportQueueWorker extends QueueWorkerBase implements ContainerFactoryPluginInterface
{
public function __construct(array $configuration, $plugin_id, $plugin_definition) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition
);
}
/**
* {@inheritdoc}
*/
public function processItem($projectId) {
// Je recommande l'injection de dépendance, mais pour l'exemple j'appel un service en statique
/** @var ProjectService $projectService */
$projectService = Drupal::service('Drupal\my_module\services\ProjectService');
// Méthode de mon service qui fait un appel http avec Guzzle et qui envoie des alertes si la réponse n'est pas bonne (différent de 200)
$projectService->checkStatusCodeOfSite((int)$projectId);
Drupal::logger('cron')->notice('Run queue for status code project !');
}
}
Voici notre QueueWorker.
La fonction processItem est une méthode de traitement des éléments d'une file d'attente dans Drupal. Elle est appelée pour chaque élément de la file d'attente lorsque la file d'attente est traitée.
La première étape consiste à appeler un service qui permet de gérer les projets et les rapports d'état associés. $projectId est le paramètre passé à la fonction, qui représente l'identifiant du projet pour lequel la vérification du code d'état de la page d'accueil doit être effectuée. Lorsque cette tâche sera exécutée, elle enregistrera un message dans les journaux de Drupal.
Une fois tout cela fait, dans notre liste de sites, nous pouvons savoir avec un code couleur par exemple si un site web est hors service ou non de manière automatique.
Pour en savoir plus sur les QueueWorkers, je vous conseille 2 autres articles :
Cet article vous a été utile ? Je vous conseille de lire également les articles suivants :
Crédit photo : Maximusnd