Skip to content

Event Stream

Duncan Jones edited this page May 17, 2020 · 8 revisions

Event Stream

An event stream is the sequential history of all the events that have occurred to an entity over its life history.

Each event stream (and by logical inference each entity) is uniquely identified by the combination of three values - the domain, the entity type and the entity instance key.

For example in a retail banking situation you might have account entities identified as:-

  • Bank - Account - A123456789
  • Bank - Account - A234567890

and maybe branches identified as

  • Bank - Branch - 901028
  • Bank - Branch - 901030

The combination of these three values is used by the underlying library in order to decide which event stream to append new events to (for a command) and which event stream to run a projection over (for a query).

This combination can also be used to determine if a given entity already exists or not.

Implementations

Table (NoSQL)

In the Azure Table implementation the domain is used to navigate to the storage account that holds the table, the entity type is used to get the table name and the entity instance identifier is used as the partition key field for each row of the table. The second part of the key - the row key field - is the event sequence number (0 padded) and the event details are held in the non key fields of the record.

There are special fields (e.g. EventType ) for the event context information.

The record with a row key of 0000000000 is the information record that holds the current sequence number and context information for the whole event stream for the instance unique identifier. Access to this record enforces concurrency checking.

AppendBlob

In the AppendBlob based implementation, each event stream is contained in its own blob with the path and blob name made from the combination of the domain, the entity type and the entity instance key.

For example the path for the first bank account would be:-

Bank/eventstreams/Account/A123456789.events

If the domain name, entity type or entity instance key contain characters that are not valid for an Azure blob name they are replaced with a dash (-) and the original values are stored in the named attributes of that Azure blob.

An example of that data in the blob would look something like:

[
  {
    "$type": "EventSourcingOnAzureFunctions.Common.EventSourcing.Implementation.AzureStorage.AppendBlob.BlobBlockJsonWrappedEvent, EventSourcingOnAzureFunctions.Common",
    "EventTypeName": "EventSourcingOnAzureFunctions.Common.EventSourcing.Implementation.EventInstance",
    "VersionNumber": 1,
    "SequenceNumber": 1,
    "EventInstanceAsJson": {
      "EventTypeName": "Account Opened",
      "EventPayload": {
        "LoggedOpeningDate": "2019-05-29T20:41:49.4357208Z",
        "Commentary": "Initial open account testing "
      }
    },
    "WriteTime": "2019-05-29T21:00:00"
  },
  {
    "$type": "EventSourcingOnAzureFunctions.Common.EventSourcing.Implementation.AzureStorage.AppendBlob.BlobBlockJsonWrappedEvent, EventSourcingOnAzureFunctions.Common",
    "EventTypeName": "EventSourcingOnAzureFunctions.Common.EventSourcing.Implementation.EventInstance",
    "VersionNumber": 1,
    "SequenceNumber": 2,
    "EventInstanceAsJson": {
      "EventTypeName": "Money Deposited",
      "EventPayload": {
        "AmountDeposited": 1200.00,
        "Commentary": "Opening deposit",
        "Source": null,
        "TransactionCorrelationIdentifier": null,
        "LoggedDepositDate": "2019-05-29T21:41:49.4357208Z",
        "ExpectedFundsClearedDate": "2019-06-04T00:00:00"
      }
    },
    "WriteTime": "2019-05-29T21:41:49"
  },
  {
    "$type": "EventSourcingOnAzureFunctions.Common.EventSourcing.Implementation.AzureStorage.AppendBlob.BlobBlockJsonWrappedEvent, EventSourcingOnAzureFunctions.Common",
    "EventTypeName": "EventSourcingOnAzureFunctions.Common.EventSourcing.Implementation.EventInstance",
    "VersionNumber": 1,
    "SequenceNumber": 3,
    "EventInstanceAsJson": {
      "EventTypeName": "Designated Benificiary Set",
      "EventPayload": {
        "BeneficiaryName": "Mr Duncan Jones",
        "CountryOfResidence": null,
        "ExistingCustomerIdentifier": null
      }
    },
    "WriteTime": "2019-05-29T22:01:49"
  }
]
Clone this wiki locally