Link Event

Intent

A Link Event is a special type of event that acts as a pointer to another event. This allows for the creation of streams that represent arbitrary indexes of events in other streams.

Problem

A bank has decided that they would like to create a stream for each account. Each stream containing the events (credit, debit, etc) for the account. When rebuilding accounts to check a balance the consumers only need to be able to replay the account stream. There are also some consumers interested in other ways of looking at the events from the accounts. As example there is one consumer who wishes to see all transactions greater than $10,000 and another consumer who wishes to see transactions based on year.

The system that handles writing and validating transactions partitions the events to streams via the account identifier. Other consumers want to look at the events in other ways, there are other consumers who might have many different desires in how to look at the events.

The issue at hand is also seen in how to replay a given projection. In the example above one projection is interested in transactions greater than $10,000. How replay this projection so that it only sees these transactions when streams are partitioned by account id?

Discussion

The Link Event is the simplest pattern discussed but it is often used in other patterns. Link Events also introduce the ability to reindex events from streams in new ways. While a simple pattern the concept of a Link Event is crucial to getting other patterns to work.

Varying Event Stores have different levels of support for the concept of a Link Event. Link Events can though can be implemented on top of any Event Store by a client library.

Implementation

At its core a Link Event operates as a pointer to another event. This is advantageous as it is smaller than the event that it points to. It also offers a level of indirection that is useful in many scenarios.

A reserved type of event is needed for Link Events say $link. The body of the Link Event is then the stream/event number that the Link Event points to.

$link {
    stream : "foo",
    sequence : 19
}

The Event Store implements this pattern in a more succinct way with an Event Type of $> and an event body of 19@foo.

Once the Link Event exists the next phase in implementation is recognizing the reserved Event Type and resolving the pointer. This process is possible on either the client or the Event Store side (Event Store does the latter). It is important to note that if you wish to have multiple replica sets (sharded) then this process happens in the client.

As example when a read occurs and you get the $link you then issue another read for stream/sequence and return the value of that read instead of the link itself.

Indexed Events When reading events from the stream John the events are Link Events that point back to the stream Incoming. This has essentially created a new stream John which is an index into all of the events in Incoming that were by John. A consumer that is interested in John events could now just read the John stream to get all of the John events as opposed to reading the entire Incoming stream.

The Link Event also is separated from the actual event. As example you could go and delete 1@Incoming and when you read the Sam stream there will be a single event in stream (2@Incoming) as the first event will not resolve. This behaviour is commonly useful in situations where data needs to be deleted.

It is also important to note that Link Events can be written at any point in time before or after the original event is written. You can for instance write a series of Link Events a year after the original events to create a new view of them.

In the Multiple Timeline pattern Link Events can also be used to provide multiple temporal viewpoints over the same series of facts.

Summary

Link Events are a powerful building block. At their core they are just pointers to other events. Link Events are lighter weight than the alternative of copying the event. As they point back to the original offer some novel behaviour around deletion.

results matching ""

    No results matching ""