Come evitare l'oscillazione dei sistemi basati su eventi asincroni?

6

Immagina un sistema in cui siano presenti fonti di dati che devono essere mantenute sincronizzate. Un semplice esempio è il modello: visualizza l'associazione dati da MVC. Ora intendo descrivere questo tipo di sistemi con origini dati e hub. Le origini dati vengono pubblicate e sottoscritte per gli eventi e gli hub trasmettono eventi alle origini dati. Gestendo un evento un'origine dati cambierà il suo stato descritto nell'evento. Pubblicando un evento, l'origine dati mette il suo stato corrente sull'evento, quindi altre fonti di dati possono utilizzare tali informazioni per modificare il loro stato di conseguenza.

L'unico problema con questo sistema, che gli eventi possono essere riflessi dall'hub o dalle altre origini dati e che possono mettere il sistema in un'oscillazione infinita (tramite sincronizzazione asincrona o infinita tramite sincronizzazione). Ad esempio

A -- data source
B -- data source
H -- hub

A -> H -> A -- reflection from the hub
A -> H -> B -> H -> A -- reflection from another data source

Per sincronizzazione è relativamente facile risolvere questo problema. Puoi confrontare lo stato corrente con l'evento e, se sono uguali, non modificare lo stato e generare nuovamente lo stesso evento.

Per async non sono riuscito a trovare una soluzione. Il confronto degli stati non funziona con la gestione degli eventi asincroni perché esiste una coerenza finale e nuovi eventi possono essere pubblicati in uno stato incoerente che causa la stessa oscillazione. Ad esempio:

A(*->x) -> H -> B(y->x)
    -- can go parallel with
B(*->y) -> H -> A(x->y)
    -- so first A changes to x state while B changes to y state
    -- then B changes to x state while A changes to y state
    -- and so on for eternity...

Cosa pensi ci sia un algoritmo per risolvere questo problema? Se esiste una soluzione, è possibile estenderla per evitare oscillazioni causate da più hub, più eventi diversi, ecc ...?

Aggiornamento:

Non penso di poter fare questo lavoro senza molti sforzi. Penso che questo problema sia lo stesso che abbiamo sincronizzando più database in un sistema distribuito. Quindi penso che ciò di cui ho veramente bisogno sono i vincoli se voglio evitare questo problema in modo automatico. Quali restrizioni suggerisci?

    
posta inf3rno 31.05.2014 - 13:49
fonte

1 risposta

6

Se hai progettato il tuo sistema in modo tale che un'origine dati cambia stato (e attiva un evento) per l'evento ogni che riceve, allora hai un sistema intrinsecamente instabile (oscillante) se quell'origine dati è coinvolto in un ciclo di eventi.

Gli unici modi per evitare le oscillazioni in un sistema del genere sono:

  1. In qualche modo assicurati che gli eventi ricevuti da tale fonte di dati non provengano da se stessi (direttamente o indirettamente attraverso altri eventi). Questo è più difficile di quanto sembri e il problema è che generalmente non vedi un errore fino a quando le oscillazioni non si verificano effettivamente.

  2. Assicurati che ogni origine dati abbia alcune combinazioni di stati ed eventi in cui ignora l'evento o almeno non attiva un nuovo evento.
    Quindi, nel caso della semplice riflessione dell'evento E, l'origine dati A dovrebbe ignorare l'evento E se è ricevuto nello stato x.
    In generale, in ogni sistema guidato da eventi ci sarà un certo numero di eventi che non hanno senso quando vengono ricevuti in determinati stati. Sono quegli eventi che dovrebbero smorzare le oscillazioni che si verificano.

La principale fonte di oscillazione che rimane sarebbero due eventi (esterni) che si verificano contemporaneamente e provare a mettere il sistema in stati diversi. Questi tipi di oscillazioni sono inerenti al sistema e dovranno essere affrontati caso per caso. In generale, ciò implicherebbe preferire uno stato rispetto all'altro e ignorare gli eventi che potrebbero innescare le oscillazioni quando vengono ricevuti nello stato preferito.

    
risposta data 31.05.2014 - 22:27
fonte

Leggi altre domande sui tag