Skip to content

feat: DynamoDB EventStore adapter #38

@PaulGrimshaw

Description

@PaulGrimshaw

Summary

Implement a DynamoDB-backed EventStore adapter (@dcb-es/event-store-dynamodb) that is fully DCB-compliant.

Approach

Pessimistic fine-grained locks + batch commit record.

  • Fine-grained locks on (eventType, tagValue) pairs — unrelated writes never conflict
  • Atomic global sequence counter for ordering
  • Batch commit record for crash-safe atomic visibility of large appends
  • Small appends (≤~40 events) use a single TransactWriteItems — zero lock overhead
  • Large appends use lock-based flow with BatchWriteItem — no size limit

Full technical design: packages/event-store-dynamodb/README.md

Key Design Decisions

  • Why not optimistic watermarks? Type-level watermarks cause false conflicts between unrelated entities of the same type. Fine-grained watermarks blow the 100-item TransactWriteItems limit on large batches.
  • Why pessimistic locks? Fine-grained locks match the natural conflict boundary (same entity, same event type). In practice, conflicts are rare — most lock acquisitions succeed immediately. No transaction size limits on event writes.
  • Crash safety: Every crash scenario is safe. Partial writes are invisible (PENDING batch). Stale locks expire via TTL.

Scope

  • Single-table DynamoDB schema + GSI design
  • Lock manager (acquire/release with TTL, deadlock prevention via sorted acquisition)
  • Append flow: small (transactional) and large (lock-based + batch commit)
  • Read flow: type/tag queries via GSIs, batch status filtering with caching
  • Sequence counter (atomic increment, range reservation)
  • Stale batch / lock cleanup strategy
  • Integration tests (localstack or DynamoDB local)
  • Tag query GSI strategy (denormalized index items vs alternatives)

Open Questions

  • Tag query GSI strategy — depends on expected query patterns and tag cardinality
  • Lock TTL value (likely 30-60s)
  • Query.all() optimisation to avoid global lock serialisation

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions