Skip to content

Instantly share code, notes, and snippets.

@ismasan
Created January 10, 2025 14:53
Show Gist options
  • Save ismasan/fdc03442db3f0efcb1140858596f545b to your computer and use it in GitHub Desktop.
Save ismasan/fdc03442db3f0efcb1140858596f545b to your computer and use it in GitHub Desktop.
Discord DDD-CQRS-ES aggregate boundaries discussion

Summary of Main Points from Discord Chat:

Scenario and Problem Statement

  • Initial Question:**
    Explores whether to use transactional consistency (a "dinner aggregate" for reservations) or eventual consistency (reservation created in a "user aggregate" with validation after the fact) for enforcing constraints like dinner capacity.
    • Example use case: A dinner reservation system where a dinner's capacity shouldn't be exceeded.

Design Considerations

  1. Consistency Boundaries:

    • Transactional (Strong Consistency): Enforces constraints immediately but might reject valid opportunities, e.g., rejecting a customer outright if full.
    • Eventual Consistency: Allows compensatory actions like waitlists, offering discounts, or next available slots, improving user experience.
    • Rule of Thumb: Keep consistency boundaries small, ideally one user or session per boundary.
  2. User Experience Perspective:

    • Users could see a "confirming reservation" page while backend processes validate capacity.
    • Polling or Updates: Use polling or web sockets to update users on reservation status without relying on synchronous responses.
    • Resilience: Redirect users to a permalink for tracking reservation state (e.g., /reservations/123), allowing reloads without losing context.
  3. Aggregate Design Insights:

    • Aggregates enforce constraints and emit correct events (e.g., "reservation confirmed" or "waitlisted").
    • Design aggregates around decision-making rather than purely around data relationships.
    • A "Dinner" aggregate could manage reservations for a specific night, but reservations themselves might better fit within their own aggregate.
    • Example framing: A "consistency boundary" exists wherever decisions require consistent knowledge (e.g., dinner capacity, reserved seats).

Examples and Frameworks for Thinking

  • Collaborative Domains:
    • Restaurant tables: Aggregates might model decisions over a single night's reservations or a specific table's availability.
    • Stadium seats: Decisions (e.g., reserving a seat) are localized to specific events or timeframes.
    • Chess or Board Games: The sequence of moves determines game state; consistency boundaries revolve around a single game's timeline.

General Principles Discussed

  1. Consistency vs. Context:

    • Consistency is tied to decision-making, not to the data model itself.
    • State is situational to a decision and doesn't exist in isolation.
  2. Granularity of Aggregates:

    • Design aggregates to include only the state required to make the decisions they're responsible for.
    • Use eventual consistency when real-time correctness isn't critical, reserving aggregates for decisions that must always be correct.
  3. Business Context Drives Design:

    • Stakeholders prioritize service-level objectives (e.g., speed of response) over technical consistency concerns.

Future Discussion:

  • Questioner plans to explore repository locking mechanisms for handling methods shared across multiple application services.

This discussion was rich with insights into distributed systems design, focusing on user experience, aggregate modeling, and consistency trade-offs.

  1. The discussion started with a question about when to use strong consistency (aggregates) versus eventual consistency, using a dinner reservation system as an example.

  2. Main insights about consistency and design:

  • Consistency boundaries should generally be kept small, ideally supporting single-concurrent-user operations
  • Eventual consistency can sometimes provide better business solutions, allowing for compensatory measures (like waitlists or discounts) rather than simple rejections
  • Consistency boundaries are discovered rather than defined, based on what decisions need to be made together
  1. Key principles about aggregates:
  • Aggregates should contain only the information needed to make specific decisions correctly
  • They're not about data model consistency, but about decision/command consistency
  • The boundary should include "all and only" what's needed to make the decision
  • Data exists only in context of the decisions being made
  1. Practical examples discussed:
  • Restaurant reservations: Breaking down the process into separate concerns (placing order vs. reserving space)
  • Stadium seating: Simpler example showing how capacity management works
  • Board games (especially Othello): Used to demonstrate how state and decisions work together
  • Chess: Example of how game moves form a timeline
  1. User Experience Considerations:
  • Instead of simple spinners, consider using permalinks for reservation status
  • Allow for status checking, polling, or push updates
  • Design for interruptions (page reloads, closing windows)
  1. System Design Perspective:
  • Think of boundaries like referees/arbiters managing separate games
  • Different games (or reservations) don't affect each other
  • Information can be partitioned into logical subsets that don't interact
  • Focus on service level objectives rather than just consistency

The conversation helped transform the original understanding from a data-centric view of aggregates to a decision-centric view, emphasizing that consistency boundaries should be built around the decisions that need to be made rather than around data relationships.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment