Skip to content

Class ClickHouseEventStore

Namespace: Cephalon.EventSourcing.ClickHouse
Assembly: Cephalon.EventSourcing.ClickHouse.dll

ClickHouse-backed implementation of using a MergeTree table ordered by (stream_id, stream_version) for efficient per-stream range scans and append operations.

public sealed class ClickHouseEventStore : IEventStore, IDisposable

objectClickHouseEventStore

IEventStore, IDisposable

object.Equals(object?), object.Equals(object?, object?), object.GetHashCode(), object.GetType(), object.ReferenceEquals(object?, object?), object.ToString()

Known limitation — optimistic concurrency: ClickHouse MergeTree does NOT enforce uniqueness on the ORDER BY key. Two concurrent writers that both observe the same expectedVersion can both INSERT successfully — there is no database-level rejection. The pre-read version check in catches most single-process conflicts and throws , but a race window remains between the version read and the INSERT. For strict concurrency control, wrap append operations in application-layer distributed locking.

ClickHouse is optimized for append-heavy analytics workloads. This provider is well-suited to high-throughput event append scenarios where occasional duplicate detection at the application layer is acceptable.

Initializes a new instance of the class.

public ClickHouseEventStore(string connectionString, string tableName)

connectionString string

The ClickHouse ADO.NET connection string.

tableName string

The ClickHouse table name used to persist event stream rows.

AppendAsync(string, IReadOnlyCollection<IDomainEvent>, long, CancellationToken)

Section titled “ AppendAsync(string, IReadOnlyCollection<IDomainEvent>, long, CancellationToken)”

Appends one or more events to the requested stream after checking the expected version.

public Task AppendAsync(string streamId, IReadOnlyCollection<IDomainEvent> events, long expectedVersion, CancellationToken cancellationToken = default)

streamId string

The stable stream identifier.

events IReadOnlyCollection<IDomainEvent>

The events to append.

expectedVersion long

The current stream version expected by the caller. Use -1 to require a brand-new stream.

cancellationToken CancellationToken

The token that cancels the operation.

Task

A task that completes when the append finishes.

Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.

public void Dispose()

GetVersionAsync(string, CancellationToken)

Section titled “ GetVersionAsync(string, CancellationToken)”

Gets the latest version known for the requested stream.

public Task<long> GetVersionAsync(string streamId, CancellationToken cancellationToken = default)

streamId string

The stable stream identifier.

cancellationToken CancellationToken

The token that cancels the operation.

Task<long>

A task that returns the current stream version, or -1 when the stream does not exist.

ReadStreamAsync(string, long, CancellationToken)

Section titled “ ReadStreamAsync(string, long, CancellationToken)”

Reads the requested stream from the supplied version onward.

public IAsyncEnumerable<IDomainEvent> ReadStreamAsync(string streamId, long fromVersion = 0, CancellationToken cancellationToken = default)

streamId string

The stable stream identifier.

fromVersion long

The first stream version to include. The default is 0.

cancellationToken CancellationToken

The token that cancels the operation.

IAsyncEnumerable<IDomainEvent>

An async sequence of domain events in ascending stream-version order.