dotnet-cqrs/docs/event-streaming/fundamentals
2025-12-11 01:18:24 -05:00
..
ephemeral-streams.md this is a mess 2025-12-11 01:18:24 -05:00
events-and-workflows.md this is a mess 2025-12-11 01:18:24 -05:00
getting-started.md this is a mess 2025-12-11 01:18:24 -05:00
persistent-streams.md this is a mess 2025-12-11 01:18:24 -05:00
README.md this is a mess 2025-12-11 01:18:24 -05:00
subscriptions.md this is a mess 2025-12-11 01:18:24 -05:00

Event Streaming Fundamentals

Core concepts and patterns for event streaming.

Overview

This section covers the fundamental concepts needed to use event streaming in Svrnty.CQRS. You'll learn about stream types, event design, subscriptions, and workflows.

Topics

Getting Started

Create your first event stream and publish/consume events:

  • Installation and configuration
  • Publishing events to persistent streams
  • Reading events from streams
  • Using ephemeral streams for queuing

Persistent Streams

Event sourcing with append-only logs:

  • Append-only event logs
  • Offset-based reading
  • Event replay capabilities
  • Audit log patterns
  • Event versioning

Ephemeral Streams

Message queue semantics:

  • Dequeue with visibility timeout
  • At-least-once delivery
  • Acknowledge/nack messages
  • Dead letter queue handling
  • Background job processing

Events and Workflows

Designing events and workflows:

  • Event naming conventions
  • Event payload design
  • Domain events vs integration events
  • Workflow pattern
  • Event metadata and correlation

Subscriptions

Subscription modes and patterns:

  • Broadcast subscriptions (all events)
  • Queue subscriptions (load balanced)
  • Persistent vs ephemeral subscriptions
  • Subscription lifecycle
  • Error handling in subscriptions

Quick Reference

Stream Types

Type Storage Reading Use Case
Persistent Append-only log Offset-based Event sourcing, audit logs
Ephemeral Queue Dequeue with timeout Background jobs, notifications

Delivery Modes

Mode Semantics Consumer Behavior
Broadcast At-least-once All consumers receive all events
Queue Exactly-once per group One consumer per event (load balanced)

Common Operations

Persistent Stream:

// Append events
await store.AppendAsync("orders", new[] { orderPlaced });

// Read from offset
await foreach (var evt in store.ReadStreamAsync("orders", fromOffset: 0))
{
    ProcessEvent(evt);
}

Ephemeral Stream:

// Enqueue message
await store.EnqueueAsync("email-queue", sendEmailCommand);

// Dequeue with timeout
var msg = await store.DequeueAsync("email-queue", TimeSpan.FromMinutes(5));
await ProcessMessageAsync(msg);
await store.AcknowledgeAsync("email-queue", msg.MessageId);

Key Concepts

Events are Immutable

Once appended, events cannot be modified:

// ✅ Good - Append new compensating event
await store.AppendAsync("orders", new[] {
    new OrderCancelledEvent { OrderId = 123, Reason = "Customer request" }
});

// ❌ Bad - Never modify existing events
// Events are immutable!

Events Record Facts

Events describe things that have happened (past tense):

// ✅ Good - Past tense, describes what happened
public record OrderPlacedEvent
{
    public int OrderId { get; init; }
    public DateTimeOffset PlacedAt { get; init; }
}

// ❌ Bad - Present tense or imperative
public record PlaceOrderEvent { }
public record OrderPlaceCommand { }  // This is a command, not an event

Correlation IDs

Track related events across boundaries:

await store.AppendAsync("orders", new[]
{
    new OrderPlacedEvent
    {
        OrderId = 123,
        CorrelationId = "abc-123",  // Links to original request
        CausationId = commandId     // Links to command that caused this
    }
});

Event Design Principles

  1. Single Responsibility: One event type per business fact
  2. Self-Contained: Include all data needed to process
  3. Versioned: Plan for schema evolution
  4. Idempotent: Handlers should handle duplicates gracefully
  5. Descriptive: Event names clearly describe what happened

Next Steps

  1. Start with Getting Started for hands-on introduction
  2. Learn Persistent Streams for event sourcing
  3. Understand Ephemeral Streams for message queues
  4. Design events using Events and Workflows
  5. Configure Subscriptions for consuming events

See Also