Come si usano i Job, e come si gestiscono le Code in Laravel 11

laravel queue

Il framework Laravel 11 ha una varietà di funzionalità e strumenti per sviluppare Software puliti ed evoluti, incluse le Laravel Queue

Le queue ci consentono di organizzare attività dispendiose in termini di tempo, come l’invio di e-mail o la generazione di report, da elaborare in background, liberando la tua applicazione per gestire altre richieste.

In questo articolo parliamo di come configurare e utilizzare le queue Laravel, insieme ad alcuni esempi per illustrarne l’uso pratico.

Tempo di lettura stimato: 5 minuti

Configurazione del driver della queue

Laravel supporta diversi driver di coda, tra cui Redis, Amazon SQS e Beanstalkd. È possibile selezionare il driver appropriato per la propria applicazione in base ai requisiti e all’ambiente specifici.

Per configurare il driver della coda, vai al nel file .env nella directory root dell’applicazione Laravel e imposta la variabile QUEUE_CONNECTION sul driver che desideri utilizzare:

QUEUE_CONNECTION=redis

Creazione della classe Job

Successivamente, dovrai creare una classe Job che rappresenti l’attività che desideri elaborare. Le Job classi estendendo l’interfaccia Illuminate\Contracts\Queue\ShouldQueue, il che indica che il lavoro può essere aggiunto alla coda.

Ad esempio, creiamo un lavoro che invia un’e-mail a un utente:

php artisan make:job SendEmailJob

Ciò creerà una nuova classe di lavoro nella directory app/Jobs. È possibile definire la logica del lavoro nel metodo handle:

<?php

namespace App\Jobs;

use App\Models\Podcast;
use App\Services\AudioProcessor;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

class SendEmailJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

protected $user;

/**
* Create a new job instance.
*/
public function __construct(User $user)
{
$this->user = $user;
}

/**
* Execute the job.
*/
public function handle()
{
Mail::to($this->user->email)->send(new \App\Mail\WelcomeEmail($this->user));
}
}

In questo esempio, possiamo notare che passiamo un modello Eloquent direttamente nel costruttore del Job in queue. Grazie alla SerializesModels utilizzata dal Job, i modelli Eloquent e le relative relazioni caricate verranno serializzate durante l’elaborazione del Job.

Ciò vuol dire che se il Job in coda accetta un modello Eloquent nel suo costruttore, solo l’identificatore del modello verrà serializzato nella queue. Quando il job viene effettivamente gestito, il sistema di queue recupererà automaticamente l’istanza del modello completo e le relative relazioni caricate dal database. Questo approccio alla serializzazione del modello consente di inviare payload di job molto più piccoli al driver della queue.

Dispatch del Job alla queue di Laravel

Dopo aver definito la classe del job, possiamo mandarlo alla queue utilizzando il metodo dispatch. Ad esempio, facciamo la dispatch del Job SendEmailJob, fornendo l’oggetto $user come parametro:

$user = User::find(1);
dispatch(new SendEmailJob($user));

In alternativa, possiamo utilizzare il metodo dispatchNow per eseguire immediatamente il lavoro senza aggiungerlo alla coda:

dispatch_now(new SendEmailJob($user));

Esistono diverse modalità o condizioni per il dispatch di un Job, per approfondire l’utilizzo di questi metodi, ti consiglio di leggere la documentazione di Laravel 11 cliccando qui. In particolare:

Processo della queue di Laravel

Per elaborare i job in queue, dovrai avviare un worker della queue. Per far questo Laravel fornisce il comando php artisan queue:work, che esegue un worker che interroga continuamente la queue ed elabora i job non appena diventano disponibili.

php artisan queue:work

Puoi anche specificare il nome della queue e il numero di thread di lavoro utilizzando le opzioni --queuee --tries:

php artisan queue:work --queue=emails --tries=3

Verrà eseguito un worker che elabora i job dalla queue emails e ritenta i lavori non riusciti fino a tre volte.

Monitor della queue

Puoi monitorare lo stato dei job in coda utilizzando il pacchetto Laravel Horizon, che fornisce una dashboard che visualizza informazioni sui worker in queue, sui job e sui job non riusciti.

Per installare e configurare Laravel Horizon, esegui il comando seguente:

composer require laravel/horizon

Gestione sovrapposizioni dei Jobs

Laravel include un middleware che consente di evitare sovrapposizioni di Job: Illuminate\Queue\Middleware\WithoutOverlapping. Ad esempio, supponiamo che un job in queue modifica una risorsa che dovrebbe essere modificata in modo esclusivo.

Ad esempio un credito, un saldo ecc… . Cioè informazioni che quando aggiornate, non possono essere aggiornate contemporaneamente da altri processi.

A tale scopo, possiamo restituire il metodo WithoutOverlapping dal metodo del job middleware:

use Illuminate\Queue\Middleware\WithoutOverlapping;
 
/**
 * Get the middleware the job should pass through.
 *
 * @return array<int, object>
 */
public function middleware(): array
{
    return [new WithoutOverlapping($this->user->id)];
}

Eventuali lavori sovrapposti dello stesso tipo verranno rilasciati nuovamente nella coda. È inoltre possibile specificare il numero di secondi che devono trascorrere prima che venga effettuato un nuovo tentativo di eseguire il lavoro rilasciato:

public function middleware(): array
{
    return [(new WithoutOverlapping($this->order->id))->releaseAfter(60)];
}

Se desideri eliminare immediatamente eventuali lavori sovrapposti in modo che non vengano ritentati, puoi utilizzare il metodo dontRelease:

public function middleware(): array
{
    return [(new WithoutOverlapping($this->order->id))->dontRelease()];
}

Il middleware WithoutOverlapping è alimentato dalla funzione di blocco atomico di Laravel. A volte, il lavoro potrebbe fallire inaspettatamente o scadere in modo tale che il blocco non venga rilasciato. Pertanto, è possibile definire esplicitamente una data di scadenza del blocco utilizzando il metodo expireAfter. Ad esempio, l’esempio seguente istruirà Laravel a rilasciare il blocco WithoutOverlapping tre minuti dopo l’inizio dell’elaborazione del lavoro:

public function middleware(): array
{
    return [(new WithoutOverlapping($this->order->id))->expireAfter(180)];
}

Le queue Laravel forniscono un modo potente per gestire attività che richiedono molto tempo in background, consentendo alla tua applicazione di gestire altre richieste in modo efficiente. Seguendo i passaggi descritti in questo articolo, puoi facilmente configurare e utilizzare le code Laravel nella tua applicazione. Con la possibilità di monitorare e gestire la coda utilizzando Laravel Horizon, puoi garantire che la tua applicazione funzioni in modo fluido ed efficiente. Utilizzando le code Laravel, puoi fornire un’esperienza utente migliore ai tuoi clienti e migliorare le prestazioni complessive della tua applicazione.

Letture Correlate

Ercole Palmeri

Autore