172 lines
4.4 KiB
Markdown
172 lines
4.4 KiB
Markdown
# 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](getting-started.md)
|
|
|
|
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](persistent-streams.md)
|
|
|
|
Event sourcing with append-only logs:
|
|
|
|
- Append-only event logs
|
|
- Offset-based reading
|
|
- Event replay capabilities
|
|
- Audit log patterns
|
|
- Event versioning
|
|
|
|
### [Ephemeral Streams](ephemeral-streams.md)
|
|
|
|
Message queue semantics:
|
|
|
|
- Dequeue with visibility timeout
|
|
- At-least-once delivery
|
|
- Acknowledge/nack messages
|
|
- Dead letter queue handling
|
|
- Background job processing
|
|
|
|
### [Events and Workflows](events-and-workflows.md)
|
|
|
|
Designing events and workflows:
|
|
|
|
- Event naming conventions
|
|
- Event payload design
|
|
- Domain events vs integration events
|
|
- Workflow pattern
|
|
- Event metadata and correlation
|
|
|
|
### [Subscriptions](subscriptions.md)
|
|
|
|
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:**
|
|
```csharp
|
|
// 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:**
|
|
```csharp
|
|
// 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:
|
|
|
|
```csharp
|
|
// ✅ 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):
|
|
|
|
```csharp
|
|
// ✅ 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:
|
|
|
|
```csharp
|
|
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](getting-started.md) for hands-on introduction
|
|
2. Learn [Persistent Streams](persistent-streams.md) for event sourcing
|
|
3. Understand [Ephemeral Streams](ephemeral-streams.md) for message queues
|
|
4. Design events using [Events and Workflows](events-and-workflows.md)
|
|
5. Configure [Subscriptions](subscriptions.md) for consuming events
|
|
|
|
## See Also
|
|
|
|
- [Event Streaming Overview](../README.md)
|
|
- [Consumer Groups](../consumer-groups/README.md)
|
|
- [Projections](../projections/README.md)
|
|
- [Event Sourcing Tutorial](../../tutorials/event-sourcing/README.md)
|