Controllo degli errori nel paradigma basato sugli attori

4

Ho un'applicazione Scala che sto tentando di refactare per usare Akka . Uno dei problemi che ho è come gestire il controllo degli errori nelle applicazioni basate su attori.

Di solito il controllo degli errori viene eseguito attraverso uno dei due meccanismi:

  • o uno restituisce un valore che indica una condizione di errore, ad esempio Option[A] o Failure[A] o
  • mediante l'uso di eccezioni.

Nessuno di questi stili sembra particolarmente utile qui. Da un lato, i messaggi degli attori sono solitamente "fuoco e dimentica", quindi non ci sono valori di ritorno. [Si può avere un valore di ritorno usando Futures, ma certamente non è consuetudine chiedere il futuro su ogni messaggio.] D'altra parte, l'elaborazione del messaggio di solito avviene su un altro thread, così che non si può cogliere un'eccezione derivante dall'elaborazione di un messaggio.

Si potrebbe simulare il primo meccanismo inviando messaggi di errore o di conferma, come

class FooActor extends Actor {
  def receive = {
    case Foo => ...
      if (errorCondition) sender ! ErrorMessage
  }
}

Ma se si deve fare questo per ogni attore, diventa un grosso problema e sembra una simulazione da povero dello srotolamento dello stack.

What is a good strategy to recover from errors in actor-based applications?

    
posta Andrea 31.01.2013 - 14:43
fonte

2 risposte

1

In base al tuo esempio con la mancata connessione al database, penso che sia necessario presentare un altro attore. Questo attore contiene una coda dei messaggi che contengono i dati che devono essere scritti nel database. Quindi l'attore che mantiene la connessione al database richiede il successivo messaggio da salvare nel database inviando un messaggio all'attore della coda. Quindi, un messaggio contenente i dati da salvare viene inviato all'attore del database e, in caso di salvataggio riuscito, l'attore del database invia un messaggio all'attore della coda che indica un salvataggio riuscito. A questo punto, il messaggio appena salvato può essere rimosso dalla coda e il messaggio successivo inviato all'attore del database, se ce n'è uno. Tuttavia, se l'attore del database si arresta in modo anomalo, il messaggio che indica il salvataggio riuscito non viene mai inviato e quindi il messaggio è ancora nell'attore della coda. Quando l'attore del database inizia a eseguire il backup, comunica semplicemente all'attore della coda che è pronto per l'elaborazione e il messaggio precedente che non è stato salvato nel database verrà nuovamente inviato.

    
risposta data 06.02.2013 - 23:34
fonte
2

La tolleranza ai guasti è uno dei concetti chiave di Akka e "lasciarlo andare in crash" è uno dei loro motti. Il meccanismo di Akka per la gestione dei guasti è chiamato supervisione, ed è proprio lì su akka.io/#supervision :

Actors form a tree with actors being parents to the actors they've created. As a parent, the actor is responsible for handling its children’s failures (so-called supervision), forming a chain of responsibility, all the way to the top. When an actor crashes, its parent can either restart or stop it, or escalate the failure up the hierarchy of actors. This enables a clean set of semantics for managing failures in a concurrent, distributed system and allows for writing highly fault-tolerant systems that self-heal. Learn more.

Quindi, non è necessario esplicitamente generare messaggi di errore in caso di eccezione. La strategia di supervisione del genitore di un attore (o del genitore del genitore e così via) viene invocata automaticamente. Anche se puoi ovviamente farlo se vuoi.

Dai anche un'occhiata a Supervisione , Monitoraggio del ciclo di vita e Riavvia hook .

    
risposta data 31.01.2013 - 19:32
fonte

Leggi altre domande sui tag