Vai al contenuto
DedicatedPHP Contatto

Come progettare una coda di attività per operazioni lente in PHP

Scopri quando spostare un’operazione fuori dalla richiesta web e come gestire in sicurezza stati, avanzamento, risultati, annullamento ed errori.

Schema concettuale del ciclo di vita di un’attività PHP: in attesa, in elaborazione, completata, non riuscita o annullata

Un’operazione che richiede diversi secondi può lasciare aperta una richiesta HTTP, consumare risorse del server web e offrire all’utente un’esperienza incerta se la connessione si interrompe. I processi in background in PHP consentono di accettare il lavoro ed eseguirlo al di fuori del ciclo di vita di quella richiesta. Perché la soluzione sia utile, non basta aggiungere una coda: occorre definire cosa riceve l’utente, come consulta lo stato e cosa accade in caso di interruzione.

Individuare le operazioni da eseguire in background

Individuare le operazioni da eseguire in background — guía visual de DedicatedPHP

È opportuno valutare l’impatto di un’operazione, senza applicare una regola basata unicamente sulla sua durata. Un’attività può essere candidata se la sua durata è variabile, richiede di attendere un sistema esterno o elabora molti elementi. Alcuni esempi sono generare un report esteso, importare un file, trasformare documenti o sincronizzare dati con un’API.

Se invece l’utente ha bisogno di una decisione immediata per proseguire — come convalidare un dato essenziale prima del salvataggio — può essere preferibile mantenere quella parte nella richiesta e separare solo il lavoro successivo. Esistono anche attività lente che, per requisiti aziendali, richiedono una risposta sincrona. L’architettura deve rispondere alle esigenze del flusso, senza trasformare ogni operazione in un’attività asincrona.

Prima di modificare il design, individua quanto dura l’operazione, quale parte assorbe quel tempo e cosa accade in caso di errore. Una coda non corregge da sola query inefficienti, limiti configurati male o dipendenze esterne instabili; può trasferire questi problemi ai worker in background.

Rispondere che l’attività è stata accettata, non inventare un risultato

Quando il lavoro viene accettato per l’esecuzione successiva, la risposta dell’applicazione deve distinguere chiaramente tra accettato e completato. Può restituire un identificativo dell’attività e indicare che l’elaborazione è in attesa. Non deve presentare come completato un risultato che ancora non esiste.

Una stima della durata è appropriata solo se ci sono informazioni sufficienti per calcolarla e comunicarne l’incertezza. In molti sistemi è più onesto mostrare uno stato come “in coda” o “in elaborazione” che promettere un orario di completamento. Se l’attività può essere completata rapidamente, l’interfaccia può comunque consultare lo stato e mostrare il risultato quando è disponibile, senza bloccare la richiesta originale.

Definisci anche cosa accade se l’invio alla coda non riesce: l’applicazione non deve confermare l’accettazione se non è in grado di registrare il lavoro in modo affidabile. Il meccanismo specifico dipende dall’architettura, ma la risposta e lo stato persistito devono essere coerenti.

Definire stati e transizioni valide

Un ciclo di vita essenziale ed esplicito facilita l’esperienza utente e la gestione operativa. Come base, si possono prevedere pendiente, en_proceso, cancelacion_solicitada, completada, fallida e cancelada. I nomi possono variare; le transizioni, invece, devono essere valide e verificabili, non una combinazione libera di stati.

  • Transizioni normali: pendiente → en_proceso e, da en_proceso, completada o fallida.
  • Annullamento prima dell’avvio: pendiente → cancelada se si conferma che il worker non ha ancora iniziato il lavoro.
  • Annullamento durante l’esecuzione: en_proceso → cancelacion_solicitada. Da questo stato, l’attività passa a cancelada se viene interrotta in sicurezza; può passare a completada se termina prima che la richiesta venga gestita, oppure a fallida se si verifica un errore.
  • Stati finali: completada, fallida e cancelada non dovrebbero tornare a stati attivi. Se è consentito ripetere un’attività, crea una nuova esecuzione o definisci esplicitamente un ciclo diverso.

Il sistema deve impedire le transizioni non consentite e registrare quando si è verificato ogni cambiamento. Se un worker viene interrotto e lascia un’attività in en_proceso, non contrassegnarla automaticamente come completata. Una policy di recupero può riportarla a pendiente quando è sicuro riprenderla oppure contrassegnarla come fallida per una revisione. La decisione dipende dalla possibilità di riprendere il lavoro senza duplicare gli effetti. Il coordinamento dei tentativi e l’idempotenza richiedono decisioni specifiche; non vanno confusi con il modello degli stati visibile all’utente.

Comunicare avanzamento, risultati ed errori

L’avanzamento dovrebbe basarsi su traguardi misurabili. Se non è possibile calcolare una percentuale reale, è preferibile indicare la fase (“convalida dei dati”, “generazione del report”) oppure mantenere lo stato “in elaborazione”. Una percentuale che resta ferma o diminuisce senza spiegazioni riduce la fiducia.

Al completamento, fornisci il risultato aziendale: per esempio, un riepilogo degli elementi elaborati o un riferimento alla risorsa generata, nel rispetto delle autorizzazioni e della disponibilità. Lo stato dell’attività non deve necessariamente contenere l’intero risultato. Può memorizzare un riferimento a dati gestiti dal dominio dell’applicazione.

In caso di errore, mostra un messaggio che aiuti a decidere il passo successivo, per esempio correggere un file o riprovare, quando opportuno. Registra separatamente l’errore tecnico necessario per la diagnosi, limitandone l’accesso. Non esporre trace, credenziali, percorsi interni o dati sensibili nell’interfaccia o in un’API pubblica.

Trattare l’annullamento come una richiesta con limiti

Annullare un’attività non significa sempre che possa essere interrotta immediatamente. Un worker potrebbe essere impegnato in una chiamata esterna, nella scrittura di dati o in una fase che non ammette interruzioni sicure. Per questo l’interfaccia deve distinguere tra cancelacion_solicitada e cancelada: il primo indica che la richiesta è stata ricevuta; il secondo, che il sistema ha confermato l’interruzione.

L’implementazione può verificare la presenza di un segnale di annullamento in punti sicuri e smettere di avviare i passaggi successivi. Se l’effetto è già stato confermato in un sistema esterno, non si deve affermare che sia stato annullato. Spiega all’utente quale risultato può aspettarsi e registra chi ha richiesto l’annullamento quando questa informazione è rilevante ai fini dell’audit.

Separare il record dell’attività dal risultato aziendale

Il record di un’attività serve a coordinare l’esecuzione e la consultazione: può includere un identificativo, lo stato, le date, il richiedente e riferimenti diagnostici. Il risultato aziendale — per esempio un report o i record importati — appartiene al modello di dati che rappresenta quel risultato.

Separarli evita che un’attività contenente informazioni temporanee diventi l’unica fonte per il dominio aziendale. Consente inoltre di definire la conservazione: per quanto tempo mantenere lo stato, quando eliminare un file e quali informazioni conservare per obblighi operativi o normativi. Gli stati obsoleti non dovrebbero accumularsi senza una policy di pulizia.

Proteggere le consultazioni e limitare il consumo di risorse

Per consultare un’attività occorre disporre delle stesse autorizzazioni necessarie per consultare qualsiasi altra risorsa. L’identificativo non sostituisce il controllo degli accessi: verifica che la persona o il sistema richiedente possa visualizzare l’attività e il relativo risultato. Limita anche la frequenza e il volume delle consultazioni per evitare polling eccessivo e valuta l’uso di notifiche quando il caso d’uso non richiede aggiornamenti continui.

L’esecuzione deve prevedere limiti di concorrenza e risorse adeguati al tipo di lavoro. Troppi worker possono saturare il database, i servizi esterni o lo storage; troppo pochi possono accumulare attività e ritardare i risultati. Monitora il volume delle attività in attesa, la loro anzianità e la durata, oltre agli errori. Questi segnali aiutano a distinguere una dipendenza lenta da un problema di capacità.

Testare l’intero ciclo prima del deployment

I test di accettazione devono coprire il comportamento visibile e la persistenza, non solo verificare che il worker invochi una funzione. Controlla almeno i seguenti scenari:

  • La richiesta crea un’attività e restituisce un riferimento senza affermare che sia già terminata.
  • Un’attività completata mostra lo stato finale e consente di accedere al risultato con le autorizzazioni corrette.
  • Un’attività non riuscita comunica un messaggio sicuro e rende disponibili le informazioni diagnostiche al team autorizzato.
  • Un’attività abbandonata o interrotta non rimane “in elaborazione” a tempo indeterminato; esiste un modo operativo per rilevarla e gestirla.
  • Una richiesta di annullamento rispetta le fasi sicure e non promette di annullare effetti già prodotti.

In un sistema esistente, introduci la modifica per un’operazione circoscritta e convalida anche l’esperienza quando la coda è in ritardo o non disponibile. L’applicazione deve fornire una risposta chiara in questi casi: comunicare che non è stato possibile accettare il lavoro, offrire un’alternativa sicura o consentire all’utente di riprovare. La decisione dipende dall’impatto dell’operazione e dalle garanzie che l’azienda può sostenere.

Lista di controllo per introdurre una coda in un sistema esistente

Lista di controllo per introdurre una coda in un sistema esistente — guía visual de DedicatedPHP

Prima di abilitare l’elaborazione in background, verifica i seguenti punti con i team responsabili dell’applicazione e delle sue operazioni:

  • Ambito: è stata scelta un’operazione specifica ed è stato definito quale parte resta sincrona e quale lavoro viene eseguito in background.
  • Persistenza: l’accettazione dell’attività e il suo stato vengono salvati in modo coerente; esiste una policy per le interruzioni, il recupero e i cambiamenti di stato.
  • Contratto con l’utente: la risposta iniziale distingue l’accettazione dal completamento e l’interfaccia spiega come consultare avanzamento, risultati ed errori.
  • Autorizzazioni e dati: consultare un’attività o il suo risultato richiede un’autorizzazione; i dati memorizzati sono ridotti al minimo e l’accesso alle informazioni diagnostiche è limitato.
  • Risorse: sono stati definiti limiti di concorrenza, durata dell’esecuzione, memoria e frequenza delle consultazioni adeguati all’operazione e alle sue dipendenze.
  • Osservabilità: è possibile rilevare accumuli, attività bloccate da tempo in elaborazione, errori e durate anomale senza includere segreti nei log.
  • Conservazione: è stato deciso per quanto tempo conservare stati, risultati, file e dati diagnostici e come eliminarli in modo controllato.
  • Test e operatività: sono stati testati i percorsi di completamento, errore, annullamento e interruzione; il team sa cosa fare se la coda non accetta lavoro o accumula ritardi.

Il deployment del codice non equivale ad abilitare subito tutti i flussi: puoi introdurre gradualmente il nuovo percorso di esecuzione e verificarne i segnali prima di estenderlo. Mantieni un’alternativa operativa adeguata se la coda o i suoi worker non sono disponibili; non confermare attività che il sistema non è riuscito a registrare.

Vuoi applicare queste idee al tuo progetto?Parliamo della tua piattaforma PHP.
Visualizza il servizio correlato