Arlodotexe / OwlCore.Nomad

A lightweight event sourcing framework.
1 stars 0 forks source link

Sharing an event stream source across different event stream handlers #3

Open Arlodotexe opened 1 month ago

Arlodotexe commented 1 month ago

Apps that use Nomad don't always need to create separate event stream keys for each part of the application that uses the library (e.g. Nomad-enabled storage sync, peer sync, project data sync), even if they add a source created by another running application.

With the way event stream handlers are set up, we could use one single event stream across multiple types of event stream handlers in the same application.

In contexts where Nomad is used to converge data into a 'roaming' state this final state should never affect the event stream, meaning if the inner EventStreamEntry.TargetId are properly unique then this enables safe sourcing of multiple roaming states from a single event stream.

The only thing preventing this as of writing is that EventStream has an explicit TargetId that represents a single distributed object that the event stream applies to, which so far has acted as a sanity check but is reflected in some of our helpers in OwlCore.Nomad.Kubo and OwlCore.Nomad.Storage.Kubo.

Arlodotexe commented 21 hours ago

This has functional analogy in how the kubo-based storage implementation of nomad works, where the root object contains the full roaming dag / event stream while child objects contain a subset of the roaming dag or event stream entries. The event stream entries contain a unique TargetId, but this doesn't necessarily correspond to a roaming key.

In the storage implementation, it corresponds to an OwlCore.Storage.IStorable.Id string, which is implemented as the roaming key + a path to the item.

There's work being done to reassess the inbox AllEventStreamEntries member on IEventStreamHandler, for reasons tangential to the issue outlined here. It's unclear if this member is truly necessary given that these simply cache the resolved event stream entries for re-use or trickle-down.

The plan is to do this on the implementation and remove it from the interface, if we can.

Important distinctions:

In short, the inclusion of TargetId on event stream entries enables sharing an event stream (resolved or not) across related but distinct classes, whether they're actually published together or are aggregated at runtime.