2012-11-26 10 views
9

Sto usando il comportamento del supervisore OTP per supervisionare e riavviare i processi figli. Tuttavia, quando il bambino muore, voglio riavviarlo con lo stesso stato che aveva prima dell'incidente.Come riavviare il bambino con stato personalizzato usando il comportamento del supervisore Erlang OTP?

Se scrivo il mio supervisore personalizzato, posso solo ricevere il messaggio {EXIT, Pid, ​​Motivo} e agire di conseguenza. Quando si utilizza il comportamento del supervisore OTP, tuttavia, tutto è gestito da OTP e non ho alcun controllo su di esso. L'unica funzione di callback che implemento è init.

Esiste un approccio standard in questo caso? Come personalizzare lo stato di un bambino riavviato dinamicamente dal supervisore otp? Come ottenere Pid del processo di terminazione utilizzando OTP? O forse è possibile ottenere lo stato del bambino prima della fine, e quindi ripristinare il bambino nello stesso stato in cui si trovava prima che si arrestasse in modo anomalo?

+0

possibile duplicato di [Riavvio del processo di erlang e stato di conservazione] (http://stackoverflow.com/questions/13199528/restarting-erlang-process-and-preserving-state) –

risposta

0

Senza conoscere i dettagli su ciò che si sta facendo, posso immaginare un mondo in cui il seguente senso:

  1. il supervisore crea una tabella ETS e passa l'identificatore di tabella per ogni bambino
  2. un bambino processo inizia e, sulla base di qualche attributo dedicata del bambino, consulta la tabella ETS per cercare di stato per caricare
  3. ogni volta che lo stato di un bambino cambia scrive al tavolo ETS

Quindi, se avessi 12 processi figlio che rappresentano le 12 Tribù di Cobol, ognuno di loro userebbe il suo nome come chiave per il tavolo ETS per cercare lo stato lasciato indietro da un precedente incarnato all'avvio. E ogni processo aggiornerebbe la tabella (usando ancora il suo nome come chiave) ogni volta che il suo stato cambiava.

Il supervisore riavvierà automaticamente un figlio ucciso e il passaggio 2, sopra, verrebbe eseguito nel metodo init del figlio. Il passaggio 3 verrebbe trattato nei metodi handle_call, handle_cast e handle_info di un bambino (sto facendo alcune ipotesi sulla natura dei processi). Ci sono un certo numero di strategie di riavvio disponibili tramite il supervisore che possono anche riavviare i fratelli se lo si desidera.

Spero che questo ti dia qualche pensiero.

2

Forse riavviare con lo stesso stato non è una buona idea. Probabilmente il processo di comando dello stato errato si blocca e se si riavvia con lo stesso stato, si bloccherà di nuovo. Ma se vuoi questo, usa una risorsa esterna per tenerlo (come ets o mnesia).

0

Penso che questo tipo di personalizzazioni del comportamento del supervisore OTP non possa essere fatto facilmente. Il modo in cui sono progettati i supervisori OTP mi costringe a seguire alcune pratiche di progettazione rigorose. La cosa più importante in questo caso è che il supervisore non dovrebbe fare nient'altro che monitorare i propri figli e riavviarli in caso di interruzione anomala. Non ci dovrebbe essere alcuna logica aggiuntiva nel supervisore per non introdurre bug nei supervisori che sono parte critica dell'albero di supervisione e della tolleranza ai guasti.

quando il bambino muore voglio ripartire con lo stesso stato che aveva prima del crollo - questa è una cattiva pratica in generale, perché figlio potrebbe aver morto a causa dello stato corrotto che aveva prima di terminazione e riavviandolo con lo stesso stato in tal caso causerà sicuramente problemi

Esiste un approccio standard in questo caso? Personalizzare lo stato dei bambini all'interno del supervisore, prima di riavviarli agisce nei confronti delle buone pratiche di progettazione del supervisore. Pertanto questo tipo di attività viene solitamente svolto in modo diverso, ad esempio introducendo un altro processo, ad esempio gen_server, che sarebbe responsabile dell'avvio dei bambini tramite supervisore (supervisore: start_child) e mantenendo i monitor su tutti i processi. Questo processo aggiuntivo potrebbe eseguire qualsiasi personalizzazione richiesta prima di avviare un nuovo figlio.

Come ottenere Pid del processo di chiusura tramite OTP? - nel processo aggiuntivo che avvia i bambini tramite supervisore: start_child è possibile monitorarli e quindi ascoltare i messaggi GIÙ. Ad esempio in caso di gen_server si usa handle_info funzione di seguito:

handle_info({'DOWN', Ref, process, _Pid, _}, S) -> 
    handle_down_worker(Ref, _Pid, S). 

O forse il suo possibile per ottenere lo stato del bambino poco prima di terminazione, e quindi ripristinare il bambino per lo stesso stato che aveva prima che incidentato? - Correggetemi se ho torto ma penso che non sia possibile in Erlang inviare, insieme al messaggio 'GIÙ', lo stato del processo che il bambino aveva, appena prima della conclusione. Se ciò fosse possibile, potrei semplicemente gestire un messaggio simile a {DOWN, Pid, ​​Reason, State} e riavviare il processo con lo stesso stato o parte di esso. Ma poi, sto pensando .. Come hai potuto preservare lo stato del bambino che muore all'improvviso, che è stato ad esempio ucciso con l'uscita (Pid, uccidere)? Dubito che sarebbe possibile.

Problemi correlati