2012-01-15 5 views
12

Qualcuno può guidarmi su come il tecnico di marcia fa un nuovo tentativo quando le eccezioni sono generate o quando si verificano errori?Condizioni di errore e tentativi in ​​gearman?

Uso il client python gearman in un'app Django e i miei worker sono avviati come comando Django. Ho letto da questo blog post che tentativi da da condizioni di errore non sono semplici e che richiede sys.exit dal lato del lavoratore.

ciò è stato fissato per riprovare magari con sendFail o sendException? Anche il supporto del gearman riprova con l'algoritmo esponenziale - diciamo se un errore SMTP si verifica dopo 2, 2,4, 8, 6 secondi ecc.?

+0

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

risposta

25

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.

+5

So che è una risposta a una vecchia domanda, ma ho visto molte persone alle prese con lo stesso problema e credo valga la pena fornire una volta per tutte il quadro completo. – Aurimas