Come dovrebbero le macchine di stato gestire le eccezioni nelle azioni?

4

Macchine di stato, ad esempio macchine di stato UML, statecharts o altre macchine a stati finiti, consentono di eseguire azioni quando una macchina a stati effettua una transizione tra stati o è all'interno di uno stato.

Neilinguaggidiprogrammazioneconeccezioni,possonoverificarsieccezioniall'internoditaliazioni,anchesenonsiaccettanoeccezionicontrollateperleazionineilinguaggidiprogrammazionechehannocontrollatoeccezioniononhannoconsentitotutteleeccezioni.NeilinguaggidiprogrammazionecomeJavaoAdaleeccezionifannopartedellasemanticadellinguaggio,adesempioOutOfMemoryErroroConstraint_Error,epossonoverificarsiinmoltipunti.Quindilemacchinedistatodevonogestirleinqualchemodo.

Glieventisonospessoaccodatiaunacodadieventiparidellamacchinaastatiegestitiinmodoasincrono.Pertanto,èimpossibilepropagareun'eccezioneaunchiamante.Finorahotrovatoduemetodidigestionedelleeccezioninelleazionidellemacchineastati:

  1. Richiamaunarichiamatagestoredieccezionidellamacchinaastati,deglistatidiorigineodidestinazioneodellatransizionechevieneeseguita. Il North State Framework per le macchine a stati UML usa questo metodo.
  2. Genera un evento per l'eccezione e gestisci quell'evento nella macchina a stati. Questo è stato descritto in Modellazione e analisi della gestione delle eccezioni usando gli Statecharts UML .

Tuttavia, non è chiaro per me cosa sia un'eccezione durante una transizione per la semantica delle macchine a stati. Alcune domande che ti vengono in mente sono:

  • La transizione viene eseguita quando si verifica l'eccezione?
  • È equivalente a un'espressione di guardia che restituisce false e la macchina di stato deve considerare altre transizioni in conflitto con priorità più bassa?
  • L'evento è considerato gestito o il computer di stato deve tentare di rielaborarlo dopo che è stato richiamato un gestore di eccezioni?
  • E gli effetti collaterali delle azioni delle transizioni che sono state eseguite prima che si verificasse l'eccezione?
  • Qual è la priorità dell'evento che viene generato per l'eccezione se ce n'è uno?

Più ci penso, più domande emergono. Sfortunatamente, le specifiche UML e altre descrizioni delle notazioni dei computer di stato non considerano eccezioni. Anche la Semantica precisa delle macchine di stato UML non le considera.

Hai altre idee su come gestire le eccezioni nelle macchine a stati? Quali sono le semantiche di una transizione se si verifica un'eccezione nella sua azione?

    
posta Fuhrmanator 01.06.2017 - 21:05
fonte

4 risposte

7

Le macchine di stato non hanno eccezioni, sebbene possano avere transizioni a uno stato di errore.

Non esiste una risposta "taglia unica" per come gestire gli errori. Questo dipende molto dal dominio del problema. Possibilità che considero utili:

  • Se si verifica un'eccezione, questa viene interpretata come una transizione verso uno stato di errore. Questo stato di errore può essere terminale, cioè abortisce la gestione di altri eventi. Ciò equivarrebbe in modo efficace a non gestire l'eccezione nella macchina a stati, ma a lasciarla diventare insensibile all'utente della macchina a stati. Un simile approccio sembra ragionevole se la causa dell'eccezione non risiede negli eventi, ma nella tua implementazione, cioè l'eccezione non può essere gestita dal tuo modello della macchina a stati.

  • Lo stato di errore potrebbe anche essere non terminale e offrire ulteriori transizioni. Questo corrisponde a un tentativo di cattura. Un tale approccio è particolarmente desiderabile quando la macchina a stati non deve terminare. Questo è generalmente applicabile se la causa dell'errore si trova nella sequenza di eventi e può quindi essere modellata.

Dipende da come questo si combina con la gestione degli eventi. Non puoi davvero riapplicare un evento che ha portato a un'eccezione. Di solito sarebbe opportuno consumare l'evento con la transizione a uno stato di errore.

Vorrei anche sottolineare che le macchine a stati sono spesso desiderabili perché possiamo provare molte proprietà sulla macchina di stato in anticipo, per esempio che deve terminare. È spesso possibile evitare un errore di memoria insufficiente poiché l'utilizzo della memoria di un DFA è limitato. Come tale, non ci si dovrebbe aspettare eccezioni e si dovrebbero prevedere casi di errore da prevedere come transizioni di stato esplicite: o la macchina di stato ha un bug, oppure la macchina di stato gestirà correttamente il "linguaggio" degli eventi che viene inviato al computer di stato.

    
risposta data 01.06.2017 - 21:43
fonte
3

So state machines have to handle them somehow.

No, non lo fanno.

Il modo in cui un'eccezione deve essere gestita è al di fuori del modello di macchina di stato. Hai spogliato ogni significato e ci hai lasciato con uno schema. Non puoi ignorare il contesto. Se un'eccezione dovrebbe essere recuperata da non è qualcosa che un diagramma di stato ti dice.

Ci sono molte altre considerazioni. Il sistema è ancora utilizzabile? L'utente ha perso i dati? Input non valido?

Ci sono molte cose che non hanno nulla a che fare con la tua macchina statale. Non essere ossessionato a risolvere tutto con esso

    
risposta data 01.06.2017 - 21:25
fonte
2

Per rispondere a questa domanda, dobbiamo riconoscere che le eccezioni, a loro volta, sono qualcosa di simile a una transizione di stato. Ti portano in uno stato che è definito dallo srotolamento dello stack. In pratica, è tutto ciò che sono. Sono un goto non locale.

Quindi quando si tratta di eccezioni ci sono sempre due modi per gestirli. Uno è considerarli fatali. In questo caso, ammetti di non conoscere lo stato del tuo processo (molto meno la macchina a stati in esecuzione), quindi non puoi più continuare. Se sei in una macchina a stati o qualsiasi altro tipo di codice, fatale è fatale.

L'altro approccio è identificare l'eccezione e determinare lo stato corrente del processo in base all'eccezione. Alcune API forniranno semantica per queste eccezioni. Uno comune è garantire che il sistema sottostante sia in uno stato coerente (come definito dalle ipotesi di modellazione dell'API). Alcuni specificheranno anche che il risultato sarà "come se non si fosse verificata una chiamata di funzione". Questi tipi di eccezioni forniscono garanzie che è possibile utilizzare all'interno del proprio computer di stato.

Con queste eccezioni, puoi prenderle e usarle come transizioni in stati di "errore" perché conosci abbastanza dello stato del processo per capire quali parti delle tue strutture di dati sono coerenti e quali parti non lo sono. Lo stato di errore può quindi esplorare ulteriormente lo stato corrente del processo per cercare di identificare quale stato passare alla successiva.

La chiave è che devi essere in grado di estrarre le informazioni sullo stato corrente dei tuoi dati e oggetti dall'eccezione. Se non estrai queste informazioni, non hai nulla per determinare quali invarianti sono ancora valide. Senza questi, non ti puoi fidare di nulla.

    
risposta data 14.07.2017 - 23:12
fonte
1

Dipenderà dalla tua implementazione della macchina a stati, dalla lingua e dal tipo di eccezione. Ho aggiunto il diagramma alla tua domanda per un esempio:

SefosseJavaeaction()avesseunatryperun'eccezionecontrollata,potrestigestirebenelecosesapendochelostatocorrenteeras1eeriintransitionName(as2).L'accessoatuttequestecosedipendedacomesiimplementalamacchinaastati.UMLnonrispondeaquesto.

Architettonicamente,potrestipensareaglistatiannidatieleeccezioninoncontrollatetiportanoinqualchestatodierrore:

Se riesci a gestire l'errore, decidi di conseguenza il prossimo stato. Questa potrebbe essere una transizione esplicita nel diagramma di stato, oppure no (un operatore umano potrebbe decidere). Se stai usando UML come schizzo, non vedo alcun problema nell'usare le eccezioni come transizioni.

Se ti interessano i pattern per gestire gli stati di errore (non parte di UML), mi piace il libro di Hanmer

Some errors require very drastic action. The SOMEONE IN CHARGE (8) might have overseen a series of ESCALATION (9) steps, but none of the steps resolved the error. This is a truly persistent fault.

Restarting the application can resolve the error if the fault is in the application. If the fault is in the underlying hardware or operating system/ middleware layers then the application restart will not help.

Many techniques such as ROLLBACK (32) and ROLL-FORWARD (33) recover the application by moving it to an error free state along the normal execution path.

Hanmer, Robert. Patterns for Fault Tolerant Software (Wiley Software Patterns Series) (p. 151). Wiley. Kindle Edition.

    
risposta data 14.07.2017 - 18:38
fonte

Leggi altre domande sui tag