Maison> cadre php> Laravel> le corps du texte

Comment Laravel empêche l'exécution répétée de vos tâches planifiées

步履不停
Libérer: 2019-07-03 17:56:57
original
3113 Les gens l'ont consulté

Comment Laravel empêche l'exécution répétée de vos tâches planifiées

Introduction de base

Parfois, l'exécution d'une tâche planifiée peut prendre plus de temps que nous le pensons, ce qui posera un problème——Actuellement avant que la tâche ne soit terminée , une autre tâche identique sera exécutée, entraînant une duplication de tâches.Par exemple, imaginez que nous exécutons une tâche qui génère un rapport toutes les minutes. Après un certain temps, la quantité de données devient si importante que le temps d'exécution dépasse 1 minute. Cela entraînera la génération d'une autre tâche avant l'exécution. la tâche précédente est terminée. La même tâche commence à s'exécuter.

Solution

Dans la plupart des cas, il n'y a pas de problème, mais parfois nous devons éviter cette situation pour garantir que nous obtenons les données correctes. Dans Laravel, nous pouvons le gérer via la méthodewithoutOverlapping:

$schedule->command('mail:send')->withoutOverlapping();
Copier après la connexion

Laravel vérifiera l'attributConsoleSchedulingEvent::withoutOverlappingSi la valeur est vraie, un mutex sera créé pour cette tâche, et Cette tâche ne sera que. effectuée si le mutex peut être créé.

Qu'est-ce qu'un verrou mutex ?

C'est l'explication la plus drôle que j'ai trouvée en ligne :

Lorsque nous sommes en réunion et que nous avons une discussion animée, je sors un poulet hurlant de mon bureau. Seule la personne qui tient le Poulet Screaming peut parler, si vous ne tenez pas le Poulet Screaming, vous ne pouvez pas parler. Vous ne pouvez demander des instructions à l'hôte de la réunion, et vous ne pouvez parler que lorsque vous obtenez le poulet hurlant, sinon vous ne pouvez qu'attendre. Lorsque vous avez fini de parler, remettez le poulet hurlant à l'hôte de la réunion, qui le donnera à la prochaine personne qui prendra la parole. Cela garantira que les gens ne se parlent pas, mais aussi qu'ils auront leur propre temps pour parler.

Remplacez le poulet hurlant par un verrou mutex et les personnes par des fils. Vous avez essentiellement le concept de base d'un verrou mutex.

--https://stackoverflow.com/questions/34524/...

Analyse des principes

Laravel exécute la tâche pour le premier time Un verrou mutex sera créé, puis chaque fois qu'une tâche est exécutée, il sera vérifié si le verrou mutex existe. La tâche ne sera exécutée que lorsque le verrou mutex n'existe pas. Voici la méthodewithoutOverlapping:

public function withoutOverlapping() { $this->withoutOverlapping = true; return $this->then(function () { $this->mutex->forget($this); })->skip(function () { return $this->mutex->exists($this); }); }
Copier après la connexion

Laravel crée une méthode de rappel de filtre pour indiquer au gestionnaire de planification d'ignorer les tâches pour lesquelles le mutex existe toujours, et crée également un rappel qui efface le mutex après avoir terminé l'instance de tâche. .rappel. En même temps, avant d'exécuter la tâche, Lravel effectuera la série de vérifications suivante dans la méthodeConsoleSchedulingEvent::run():

if ($this->withoutOverlapping && ! $this->mutex->create($this)) { return; }
Copier après la connexion

Alors d'où viennent les propriétés du verrou mutex ?

QuandConsoleSchedulingScheduleest instancié, Laravel vérifiera siConsoleSchedulingMutexest lié au conteneur, si c'est le cas il l'instanciera, sinon il utiliseraConsoleSchedulingCacheMutex

$this->mutex = $container->bound(Mutex::class) ? $container->make(Mutex::class) : $container->make(CacheMutex::class);
Copier après la connexion

Maintenant, quand le le gestionnaire de tâches enregistre un événement, il passera dans l'instance mutex :

$this->events[] = new Event($this->mutex, $command);
Copier après la connexion

Laravel utilise par défaut un mutex implémenté dans le cache, mais vous pouvez l'implémenter et le remplacer vous-même.

Version cache de mutex

La classe CacheMutex n'a que 3 méthodes simples, qui utilisent le nom du mutex d'événement comme clé de cache :

public function create(Event $event) { return $this->cache->add($event->mutexName(), true, 1440); } public function exists(Event $event) { return $this->cache->has($event->mutexName()); } public function forget(Event $event) { $this->cache->forget($event->mutexName()); }
Copier après la connexion

Comme nous l'avons vu auparavant, le gestionnaire enregistre un rappel post-exécution pour garantir que le mutex est supprimé lorsque la tâche est terminée. Pour une commande dans le système, sa suppression peut déjà être garantie. Cependant, pour une tâche avec une méthode de rappel, le script peut se terminer lorsque le rappel est exécuté. Par conséquent, afin d'éviter cette situation, le code suivant est ajouté à la méthodeConsoleSchedulingCallbackEvent::run()pour garantir que le mutex peut être supprimé normalement lorsque. la tâche est fermée de manière inattendue :

register_shutdown_function(function () { $this->removeMutex(); });
Copier après la connexion

Pour plus d'articles techniques liés à Laravel, veuillez visiter la colonneTutoriel Laravelpour apprendre !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!