-
Notifications
You must be signed in to change notification settings - Fork 88
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Streaming adr #1157
Merged
ch1bo
merged 8 commits into
cardano-scaling:master
from
SundaeSwap-finance:streaming-adr
Dec 14, 2023
Merged
Streaming adr #1157
Changes from 7 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
1836531
initial streaming ADR draft
cardenaso11 5c169a7
streaming persistence ADR proposal revision
cardenaso11 ca81345
Narrow and specify scope of streaming streaming ADR
cardenaso11 da760c1
Rewrite ADR29 to be about EventSource/EventSink
ch1bo 5795923
Rename ADR 29
ch1bo c0f40f4
Define events to be re-submitted on startup
ch1bo 526103f
Fix authors
ch1bo d96faca
Add Pi to authors
Quantumplation File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
--- | ||
slug: 29 | ||
title: | | ||
29. EventSource & EventSink abstractions | ||
authors: [cardenaso11, quantumplation, ch1bo] | ||
tags: [Draft] | ||
--- | ||
|
||
## Status | ||
Draft | ||
|
||
## Context | ||
|
||
* The Hydra node represents a significant engineering asset, providing layer 1 monitoring, peer to peer consensus, durable persistence, and an isomorphic Cardano ledger. Because of this, it is being eyed as a key building block not just in Hydra based applications, but other protocols as well. | ||
|
||
* Currently the `hydra-node` uses a very basic persistence mechanism for it's internal `HeadState`, that is saving `StateChanged` events to file on disk and reading them back to load and re-aggregate the `HeadState` upon startup. | ||
- Some production setups would benefit from storing these events to a service like Amazon Kinesis data stream instead of local files. | ||
|
||
* The `hydra-node` websocket-based API is the only available event stream right now and might not fit all purposes. | ||
- See also ADR [3](/adr/3) and [25](/adr/25) | ||
- Internally, this is realized as a single `Server` handle which can `sendOutput :: ServerOutput tx -> m ()` | ||
- These `ServerOutput`s closely relate to `StateChanged` events and `ClientEffect`s are yielded by the logic layer often together with the `StateChanged`. For example: | ||
```hs | ||
onInitialChainAbortTx newChainState committed headId = | ||
StateChanged HeadAborted{chainState = newChainState} | ||
<> Effects [ClientEffect $ ServerOutput.HeadIsAborted{headId, utxo = fold committed}] | ||
``` | ||
|
||
* Users of `hydra-node` are interested to add alternative implementations for storing, loading and consuming events of the Hydra protocol. | ||
|
||
# Decision | ||
|
||
* We create two new interfaces in the `hydra-node` architecture: | ||
|
||
- ```data EventSource e m = EventSource { getEvents :: m [e] }``` | ||
- ```data EventSink e m = EventSink { putEvent :: e -> m () }``` | ||
|
||
* We realize our current `PersistenceIncremental` used for persisting `StateChanged` events is both an `EventSource` and an `EventSink` | ||
|
||
* We drop the `persistence` from the main handle `HydraNode tx m`, add **one** `EventSource` and allow **many** `EventSinks` | ||
|
||
```hs | ||
data HydraNode tx m = HydraNode | ||
{ -- ... | ||
, eventSource :: EventSource (StateChanged tx) m | ||
, eventSinks :: [EventSink (StateChanged tx) m] | ||
} | ||
``` | ||
|
||
* The `hydra-node` will load events and __hydra_te its `HeadState` using `getEvents` of the single `eventSource`. | ||
|
||
* The `stepHydraNode` main loop does call `putEvent` on all `eventSinks` in sequence. Any failure will make the `hydra-node` process terminate and require a restart. | ||
|
||
* When loading events from `eventSource` on `hydra-node` startup, it will also re-submit events via `putEvent` to all `eventSinks`. | ||
|
||
* The default `hydra-node` main loop does use the file-based `EventSource` and a single file-based `EventSink` (using the same file). | ||
|
||
* We realize that the `EventSource` and `EventSink` handles, as well as their aggregation in `HydraNode` are used as an API by forks of the `hydra-node` and try to minimize changes to it. | ||
|
||
## Consequences | ||
|
||
* The default operation of the `hyda-node` remains unchanged. | ||
|
||
* There are other things called `Event` and `EventQueue(putEvent)` right now in the `hydra-node`. This is getting confusing and when we implement this, we should also rename several things first (tidying). | ||
|
||
* Interface first: Implementations of `EventSink` should specify their format in a non-ambiguous and versioned way, especially when a corresponding `EventSource` exists. | ||
|
||
* The API `Server` can be modelled and refactored as an `EventSink`. | ||
|
||
* Projects forking the hydra node have dedicated extension points for producing and consuming events. | ||
|
||
* Sundae Labs can build a "Save transaction batches to S3" proof of concept `EventSink`. | ||
* Sundae Labs can build a "Scrolls source" `EventSink`. | ||
* Sundae Labs can build a "Amazon Kinesis" `EventSource` and `EventSink`. | ||
|
||
## Out of scope / future work | ||
|
||
* Available implementations for `EventSource` and `EventSink` could be | ||
- configured upon `hydra-node` startup using for example URIs: `--event-source file://state` or `--event-sink s3://some-bucket` | ||
- dynamically loaded as plugins without having to fork `hydra-node`. | ||
|
||
* The `Network` and `Chain` parts qualify as `EventSink`s as well or shall those be triggered by `Effect`s still? |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An important consequence I would add, which is also in #1213, is that it becomes necessary to version external representation of data we share with the outside world. Perhaps this is worth mentioning here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that should be the concern of a given
EventSink
and is especially valuable if we hope to haveEventSink
andEventSource
be compatible across revisions of their implementations.