Skip to content

Commit

Permalink
update seq diagram and decision section in adr#24
Browse files Browse the repository at this point in the history
to match current implementation.
  • Loading branch information
ffakenz committed Jul 31, 2023
1 parent f711e0c commit c16766b
Showing 1 changed file with 33 additions and 24 deletions.
57 changes: 33 additions & 24 deletions docs/adr/2023-06-19_024-persistence.md
Expand Up @@ -3,12 +3,12 @@ slug: 24
title: |
24. Persist state changes incrementally
authors: [abailly]
tags: [Proposed]
tags: [Accepted]
---

## Status

Proposed
Accepted

## Context

Expand All @@ -21,35 +21,44 @@ Proposed
Implement state persistence using [_Event Sourcing_](https://thinkbeforecoding.com/post/2013/07/28/Event-Sourcing-vs-Command-Sourcing). Practically, this means:

1. Replace the `NewState` outcome with a `StateChanged` _event_ which can be part of the `Outcome` of `HeadLogic`'s `update` function, representing the _change_ to be applied to the current state.
2. Add a dedicated [handle](/adr/4) to manage `StateChanged` events, applying them, and maintaining current `HeadState`
3. Persist `StateChanged`s in an append-only log
4. Upon node startup, reread `StateChanged` events log and reapply those to reset the `HeadState`
3. _(Optional)_: Make `StateChanged` _invertible_
2. Add an `aggregateState` function to manage applying `StateChanged` events on top of the current `HeadState` to keep it updated in-memory.
3. Persist `StateChanged`s in an append-only log using a dedicated [handle](/adr/4).
4. Upon node startup, reread `StateChanged` events log and reapply those to reset the `HeadState`.
3. _(Optional)_: Make `StateChanged` _invertible_.

The following sequence diagram illustrates new event handling in the `HeadLogic`:

```mermaid
sequenceDiagram
EventQ ->> Node : nextEvent
Node ->> State : getState
activate State
State -->> Node : state: HeadState
Node ->> HeadLogic: update(state)
activate HeadLogic
HeadLogic -->> Node : [st:StateChanged, ot:OtherEffect]
Node ->> State: setState(st)
activate State
State ->> State: persist(st)
State -->> Node: ok
Node -) Other: handle(ot)
Node ->> EventQ : nextEvent
activate EventQ
EventQ -->> Node : event
deactivate EventQ
critical modifyHeadState
Node ->> State : getState
activate State
State -->> Node : state: HeadState
deactivate State
Node ->> HeadLogic: update(state, event)
activate HeadLogic
HeadLogic -->> Node : Combined (sc: StateChanged) (oe: OtherEffect)
deactivate HeadLogic
Node ->> Node: aggregateState(state, sc)
Node ->> State: setState(state)
activate State
State ->> Node: ok
deactivate State
end
Node ->> Node: append(sc)
Node -) HandleOtherEffect: processEffect(oe)
```

## Consequences

- :racehorse: The main expected consequence of this change is an increase of the overall performance of Hydra Head network
- While _Effect handlers_ might be asynchronous, `StateChanged` handler _must_ be synchronous to ensure consistency and durability of state changes
- :racehorse: The main expected consequence of this change is an increase of the overall performance of Hydra Head network.
- While _Effect handlers_ might be asynchronous, `StateChanged` handler _must_ be synchronous to ensure consistency and durability of state changes.
- An longer term consequence is the possibilities this change introduces with respect to `ServerOutput` handling and client's access to a head's state:
- Instead of having the `HeadLogic` emits directly a `ClientEffect`, the latter could be the result of a client-centric _interpretation_ of a `StateChanged`
- Pushing this a little further, we could maintain a _Query Model_ for clients with a dedicated [Query API](https://github.com/input-output-hk/hydra/discussions/686) to ease implementation of stateless clients
- Crashing nodes could catch-up with the Head's state by requesting `StateChanged` changes they are missing
- Calling `StateChanged` an _event_ while treating it in the code alongside _effects_ might introduce some confusion as we already use the word [Event](https://github.com/input-output-hk/hydra/blob/45913954eb18ef550a31017daa443cee6720a00c/hydra-node/src/Hydra/HeadLogic.hs#L64) to designate the inputs to the Head logic state machine. We might want at some later point to unify the terminology
- Instead of having the `HeadLogic` emits directly a `ClientEffect`, the latter could be the result of a client-centric _interpretation_ of a `StateChanged`.
- Pushing this a little further, we could maintain a _Query Model_ for clients with a dedicated [Query API](https://github.com/input-output-hk/hydra/discussions/686) to ease implementation of stateless clients.
- Crashing nodes could catch-up with the Head's state by requesting `StateChanged` changes they are missing.
- Calling `StateChanged` an _event_ while treating it in the code alongside _effects_ might introduce some confusion as we already use the word [Event](https://github.com/input-output-hk/hydra/blob/45913954eb18ef550a31017daa443cee6720a00c/hydra-node/src/Hydra/HeadLogic.hs#L64) to designate the inputs to the Head logic state machine. We might want at some later point to unify the terminology.

0 comments on commit c16766b

Please sign in to comment.