2012-04-28 7 views
10

Qual è un buon modo per fare in modo che un attore provi di nuovo qualcosa in caso di errore, ma con intervalli di tempo crescenti tra i tentativi? Diciamo che voglio che l'attore riprovi dopo 15 secondi, poi 30 secondi, poi ogni minuto per un numero limitato di volte.Akka: come pianificare i tentativi di fallimento con intervalli di ritardo crescenti?

Ecco cosa mi è venuta in mente:

  • il metodo dell'attore che esegue il lavoro effettivo è un optional RetryInfo parametro che, se presente, contiene il numero del tentativi siamo attualmente in
  • in caso di fallimento, l'attore sarà inviarsi una nuova ScheduleRetryMessage con retryCount + 1, poi gettare un RuntimeException
  • un altro attore supervisiona l'attore lavoratore mediante new OneForOneStrategy(-1, Duration.Inf() ritorno Resume come la sua direttiva. L'attore non ha stato, in modo Resume dovrebbe essere OK
  • sulla ricezione del ScheduleRetryMessage, l'attore sarà
    • se retryCount < MAX_RETRIES: usare scheduler di Akka per programmare l'invio di un RetryMessage dopo il ritardo desiderato
    • altro: finalmente rinunciare, l'invio di un messaggio ad un altro attore per la segnalazione degli errori

si tratta di una buona soluzione o c'è un approccio migliore?

risposta

8

Si può avere un supervisore che avvia l'attore lavoratore. Il consiglio dai doc è di dichiarare un router di dimensioni uno per il lavoratore. Il supervisore tiene traccia del numero di tentativi, quindi pianifica il messaggio inviato al lavoratore in modo appropriato.

Anche se si creerebbe un altro livello di attori, questo mi sembra più pulito dal momento che si manterrebbe la funzionalità di supervisione fuori dal lavoratore. Idealmente potresti rendere questo supervisore 1 per i lavoratori, ma penso che dovresti usare Lifecycle Monitoring per ottenere un Failure da un attore bambino. In tal caso, puoi semplicemente mantenere una mappa di [ActorRef, Int] per tenere traccia del numero di tentativi per tutti i lavoratori supervisionati. La politica di supervisione riprenderà, ma se hai raggiunto il numero massimo di tentativi, potresti inviare un PoisonPill all'attore ActorRef.

+0

Idea interessante, ci proverò. Grazie! –

7

In questi casi uso la supervisione standard. Un attore principale/supervisore definisce i tentativi in ​​una finestra temporale. Il figlio che ha effettuato un nuovo tentativo semplicemente riprogrammando il messaggio che ha causato l'errore con un ritardo in preRestart().

Se il figlio che effettua un nuovo tentativo è piuttosto complesso, è possibile prendere in considerazione l'interconnessione di un attore intermedio. Questo attore non fa che aumentare la supervisione. Su pre-riavvio, l'attore intermedio pianifica un messaggio di riavvio (ritardato). Poiché l'attore intermedio ha mantenuto il suo stato, può semplicemente riavviare l'attore lavoratore (con ritardo).

Come si può vedere la parte di ritardo potrebbe essere in pre-riavvio o all'avvio del lavoratore.

Problemi correlati