Per la mia comprensione, Gearman impiega molto "non è il mio business" approccio - per esempio, che non interviene con lavori eseguiti, a meno che non incidente lavoratori. I messaggi di successo/fallimento dovrebbero essere gestiti dal client, non dal server Gearman stesso.
In primo piano i lavori, questo implica che tutte le sendFail()
/sendException()
e altri send*()
sono diretti al cliente ed è fino al cliente di decidere se riprovare il lavoro oppure no. Questo ha senso perché a volte potresti non aver bisogno di riprovare.
Nei lavori in background, tutte le funzioni send*()
perdono il loro significato, in quanto non vi è alcun client che ascolta i callback. Di conseguenza, i messaggi inviati verranno semplicemente ignorati da Gearman. L'unica condizione in cui verrà ritentato il lavoro è quando il lavoratore si blocca (che può emulato con un comando exit(XX)
, dove XX
è un valore diverso da zero). Questo, ovviamente, non è qualcosa che si vuole fare, perché di solito si suppone che i lavoratori siano processi a esecuzione prolungata, non quelli che devono essere riavviati dopo ogni lavoro non riuscito.
Personalmente, ho risolto questo problema estendendo la classe GearmanJob predefinita, dove intercetto le chiamate alle funzioni send*()
e quindi implementando il meccanismo di ripetizione da solo. In sostanza, trasmetto tutti i dati relativi ai nuovi tentativi (numero massimo di tentativi, tempi già riprovati) insieme a un carico di lavoro e quindi gestisco tutto da solo. È un po 'macchinoso, ma capisco perché Gearman funzioni in questo modo: ti consente solo di gestire tutta la logica dell'applicazione.
Infine, per quanto riguarda la possibilità di riprovare lavori con timeout esponenziale (o qualsiasi timeout per questo). Gearman ha una funzione per aggiungere posti di lavoro in ritardo (cercare SUBMIT_JOB_EPOCH
nel protocol documentation), ma non sono sicuro circa il suo stato - l'estensione PHP e, credo, il modulo Python non lo supportano e la documentazione dicono che può essere rimosso in il futuro. Ma capisco che funzioni al momento - devi solo inviare richieste di socket raw a Gearman per farlo accadere (e anche la parte esponenziale dovrebbe essere implementata dalla tua parte).
Tuttavia, this blog post sostiene che l'attuazione SUBMIT_JOB_EPOCH non scala bene. Usa node.js e setTimeout()
per farlo funzionare, ho visto altri che usano l'utilità UNIX at
per fare lo stesso. In ogni caso - Gearman non lo farà per te. Si concentrerà sull'affidabilità, ma ti permetterà di concentrarti su tutta la logica.
sys.exit() è una cattiva idea con Gearman - tipicamente riproverà qualsiasi lavoro per sempre (a meno che non si dispone di posti di lavoro-tentativi impostati all'avvio daemon). Basta fare un 'return stringvar' con qualsiasi stato/risultato del lavoro (es. Chiave in una riga DB o cache con le informazioni reali.) – RichVel