2010-09-24 10 views
5

Ho un supervisore con due processi di lavoro: un client TCP che gestisce la connessione a un server remoto e un FSM che gestisce il protocollo di connessione.Supervisori con backoff

La gestione degli errori TCP nel processo figlio complica notevolmente il codice. Quindi preferirei "lasciarlo andare in crash", ma questo ha un problema diverso: quando il server non è raggiungibile, il numero massimo di riavvii sarà rapidamente raggiunto e il supervisore si romperà con la mia intera applicazione, il che è abbastanza indesiderabile per questo caso.

Quello che mi piacerebbe è avere una strategia di riavvio con back-off; in caso contrario, sarebbe sufficiente se il supervisore fosse a conoscenza del riavvio a causa di un arresto anomalo (ad esempio, se fosse passato come parametro alla funzione init). Ho trovato this mailing list thread, ma c'è una soluzione più ufficiale/meglio testata?

+2

I direi che la strategia nel tuo caso sembra sbagliata. Voglio dire se vuoi "lasciarlo andare in crash" ma allo stesso tempo riavviarlo immediatamente, quindi non c'è motivo di lasciarlo andare in crash perché stai solo usando il supervisore come meccanismo per i tentativi. Questo è semplicemente sbagliato imho. Dovresti lasciarlo andare in crash, inserire il codice nella sequenza di avvio se "attendi" le risorse e NON riprovare andando in crash. L'ho visto prima e di solito si tratta di un errore di progettazione piuttosto che di una limitazione nel supervisore. Cibo per la mente. –

risposta

5

È possibile trovare il nostro supervisor cushion come un buon punto di partenza. Io lo uso rallentare il riavvio su cose che devono essere in esecuzione, ma non riescono rapidamente all'avvio (come le porte che incontrano un problema di risorse).

+0

Purtroppo, sembra che ci sia un collegamento interrotto qui ... –

+1

Ho aggiornato il collegamento. Grazie per averlo indicato. – Dustin

+0

Il collegamento è nuovamente 404. –

4

Ho avuto questo problema molte volte lavorando con erlang e provato molte soluzioni. Penso che il meglio che ho trovato sia quello di avere un processo in più che viene avviato dal supervisore e avvia quello che potrebbe bloccarsi.

Avvia il bambino all'avvio, attende le uscite figlio e riavvia il bambino (con un ritardo) o esce a seconda dei casi. Penso che questo sia più semplice del server back-off (al quale si collega) in quanto è sufficiente mantenere lo stato di un singolo figlio.

Un'altra soluzione che ho utilizzato è quella di dover avviare i processi figlio come transitori e disporre di un processo separato che esegue il polling e il riavvio di eventuali processi in caso di arresto anomalo.

+0

Ha molto senso. –

1

Quindi, per prima cosa, si desidera rilevare una chiusura anticipata del bambino utilizzando un process_flag(trap_exit, true) nel proprio init.

allora avete bisogno di decidere quanto tempo si desidera ritardare un riavvio, per esempio 10 sec., Farlo nel

handle_info({'EXIT', _Pid, Reason}, State) -> 
    erlang:send_after(10000, self(), {die, Reason}), 
    {noreply, State}; 

Infine, lasciare che il processo di morire con

handle_info({die, Reason}, State) -> 
    {stop, Reason, State}; 
+1

Hello Roman e benvenuto nel sito. Ci piace mantenere le domande e le risposte molto a portata di mano qui, quindi sono andato avanti e ho ridotto la tua risposta un po '. Sentiti libero di modificarlo di nuovo se non sei soddisfatto delle mie modifiche. – MackM

Problemi correlati