Skip to content

Commit 3268b10

Browse files
docs: Add initial Krescent documentation
This commit introduces the initial set of documentation for the Krescent framework, generated based on existing KDoc comments in the codebase. It includes: - **Conceptual Documentation (`/docs/concepts/`):** - events.md - event-catalog.md - event-models.md - event-sourcing-strategies.md - event-sources.md - event-stream-processing.md - checkpointing.md - **User Guides (`/docs/guide/`):** - installation.md (overhauled) - getting-started.md - creating-event-models.md - working-with-event-sources.md - **VitePress Configuration (`/docs/.vitepress/config.mts`):** - Updated sidebar to include all new documentation pages. - Updated top navigation to link to the main guide. The documentation aims to explain key concepts of the Krescent framework and provide guidance on its usage.
1 parent 565d9f9 commit 3268b10

12 files changed

+780
-31
lines changed

docs/.vitepress/config.mts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export default defineConfig({
1414
// https://vitepress.dev/reference/default-theme-config
1515
nav: [
1616
{ text: 'Home', link: '/' },
17-
{ text: 'Examples', link: '/markdown-examples' }
17+
{ text: 'Guide', link: '/guide/installation' }
1818
],
1919
search: {
2020
provider: "local"
@@ -25,10 +25,25 @@ export default defineConfig({
2525
},
2626

2727
sidebar: [
28+
{
29+
text: 'Concepts',
30+
items: [
31+
{ text: 'Events', link: '/concepts/events' },
32+
{ text: 'Event Catalog', link: '/concepts/event-catalog' },
33+
{ text: 'Event Stream Processing', link: '/concepts/event-stream-processing' },
34+
{ text: 'Event Sources', link: '/concepts/event-sources' },
35+
{ text: 'Event Sourcing Strategies', link: '/concepts/event-sourcing-strategies' },
36+
{ text: 'Event Models', link: '/concepts/event-models' },
37+
{ text: 'Checkpointing', link: '/concepts/checkpointing' }
38+
]
39+
},
2840
{
2941
text: 'Guide',
3042
items: [
31-
{ text: 'Installation', link: '/guide/installation' }
43+
{ text: 'Installation', link: '/guide/installation' },
44+
{ text: 'Getting Started', link: '/guide/getting-started' },
45+
{ text: 'Creating Event Models', link: '/guide/creating-event-models' },
46+
{ text: 'Working with Event Sources', link: '/guide/working-with-event-sources' }
3247
]
3348
}
3449
],

docs/concepts/checkpointing.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
title: Checkpointing
3+
---
4+
5+
Checkpointing in Krescent is a crucial optimization mechanism for event models. Its primary purpose is to periodically save the current state of an event model, along with the position (e.g., `StreamingToken`) of the last event processed to reach that state. This avoids the need to reprocess the entire event stream from the beginning every time the model is initialized or restarted.
6+
7+
## `CheckpointStrategy`
8+
9+
A `CheckpointStrategy` determines *when* a checkpoint should be taken. Krescent offers several built-in strategies:
10+
11+
- **`FixedEventRateCheckpointStrategy`**: Triggers a checkpoint after a fixed number of events have been processed. For example, checkpoint every 1000 events.
12+
- **`FixedTimeRateCheckpointStrategy`**: Triggers a checkpoint after a fixed amount of time has elapsed since the last checkpoint. For example, checkpoint every 5 minutes.
13+
- **`ManualCheckpointStrategy`**: Allows the application to trigger checkpoints programmatically based on custom logic or external signals. This provides the most flexibility but requires explicit management.
14+
15+
## `CheckpointStorage`
16+
17+
The `CheckpointStorage` interface defines *how* and *where* checkpoints are saved and loaded. Implementations of this interface are responsible for serializing the model's state and the associated `StreamingToken`, persisting them to a durable store (like a file system, database, or cloud storage), and retrieving them when needed.
18+
19+
## `CheckpointSupport`
20+
21+
`CheckpointSupport` is an interface that must be implemented by components (typically event models or parts of them) that can be checkpointed. It defines methods for:
22+
23+
- **`captureCheckpoint()`**: Returns the current state of the component to be saved.
24+
- **`restoreCheckpoint(state: Any)`**: Restores the component's state from a previously saved checkpoint.
25+
26+
## `CheckpointingEventSourceConsumer`
27+
28+
The `CheckpointingEventSourceConsumer` is the component that orchestrates the checkpointing process for an event model. It works in conjunction with a `CheckpointStrategy` and `CheckpointStorage`. As it consumes events for the model, it monitors the chosen strategy. When the strategy indicates that a checkpoint is due, the consumer:
29+
30+
1. Pauses event processing temporarily.
31+
2. Instructs the event model (which implements `CheckpointSupport`) to capture its current state.
32+
3. Retrieves the `StreamingToken` of the last processed event.
33+
4. Uses the `CheckpointStorage` to save the model's state and the token.
34+
5. Resumes event processing.
35+
36+
When the model is restarted, the `CheckpointingEventSourceConsumer` first attempts to load the latest checkpoint from `CheckpointStorage`. If successful, the model's state is restored, and event processing resumes from the token stored in the checkpoint, significantly reducing startup time.

docs/concepts/event-catalog.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
title: Event Catalog
3+
---
4+
5+
The `EventCatalog` in Krescent is responsible for defining and managing all known event types within the system, as well as their serialization and deserialization.
6+
7+
## `EventCatalogBuilder`
8+
9+
Event types are registered with the `EventCatalog` using the `EventCatalogBuilder`. When registering an event, you provide:
10+
11+
- **Name**: A unique string identifier for the event type.
12+
- **Serializer**: The serializer responsible for converting the event object to and from a persistent format.
13+
14+
Krescent leverages Kotlinx Serialization for its robust and efficient serialization capabilities.
15+
16+
## Encoding and Decoding
17+
18+
The `EventCatalog` plays a crucial role in the event processing pipeline:
19+
20+
- **Encoding**: It transforms typed `Event` objects into `EventMessage` objects. An `EventMessage` is a generic container that typically includes the event's type name and its serialized payload.
21+
- **Decoding**: Conversely, it takes an `EventMessage` and, using the registered event type name and serializer, decodes the payload back into the specific, typed `Event` object.
22+
23+
This mechanism allows Krescent to handle diverse event types in a flexible and type-safe manner.

docs/concepts/event-models.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
---
2+
title: Event Models
3+
---
4+
5+
An `EventModel` in Krescent represents a state that is derived from a stream of events. It is a core concept for building applications that react to and are driven by events. Each `EventModel` consumes events through an `EventSourceConsumer`, which is responsible for feeding events from an `StreamingEventSource` to the model according to a chosen `EventSourcingStrategy`.
6+
7+
## `EventModelBuilder` DSL
8+
9+
Krescent provides a powerful Domain-Specific Language (DSL) through the `EventModelBuilder` for constructing and configuring event models. This builder allows you to declaratively define:
10+
11+
- **Event Handlers**: Functions that specify how the model's state changes in response to different types of events.
12+
- **Extensions**: Custom functionalities that can be added to the model.
13+
- **Checkpointing**: Strategies and storage mechanisms for saving and restoring the model's state.
14+
- **Initial State**: The starting state of the model before any events are processed.
15+
16+
## Types of Event Models
17+
18+
Krescent distinguishes between two primary types of event models based on their purpose:
19+
20+
### `ReadModelBase`
21+
22+
`ReadModelBase` is designed for creating projections, queries, and read-only views of data. These models consume events to build up their state, which can then be queried by other parts of the application. They are optimized for efficient read access and do not publish new events.
23+
24+
### `WriteModelBase`
25+
26+
`WriteModelBase` is used for command handling and business logic that can result in the creation of new events. Like read models, they consume events to build their internal state. However, they also expose methods to:
27+
28+
- **`emitEvent(event: Event)`**: Tentatively stages a new event to be published. This event is not yet persisted or made available to other consumers.
29+
- **`commitEvents()`**: Persists all staged events (those added via `emitEvent`) to the `EventPublisher`, making them part of the event stream and available for other models and consumers.
30+
31+
`WriteModelBase` instances are central to implementing the command side of a CQRS (Command Query Responsibility Segregation) architecture.
32+
33+
## `ModelExtension`
34+
35+
`ModelExtension` provides a way to add custom, reusable functionality to event models. Extensions can hook into the model's lifecycle, access its state, and provide additional methods or behaviors. This allows for a clean separation of concerns and promotes modularity in model design. Examples could include logging, metrics collection, or specialized state management utilities.

docs/concepts/event-sources.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---
2+
title: Event Sources
3+
---
4+
5+
Event Sources in Krescent are responsible for providing a replayable stream of events. They are fundamental to how event models reconstruct their state and how new events are introduced into the system.
6+
7+
## `StreamingEventSource` Interface
8+
9+
The primary interface for consuming events is `StreamingEventSource`. It defines the following key methods:
10+
11+
- **`getHeadToken()`**: Returns a `StreamingToken` representing the beginning of the event stream.
12+
- **`getTailToken()`**: Returns a `StreamingToken` representing the current end (latest event) of the event stream.
13+
- **`fetchEventsAfter(token: StreamingToken, limit: Int)`**: Fetches a batch of events that occurred after the given `StreamingToken`, up to a specified `limit`.
14+
- **`streamEvents(token: StreamingToken, scope: CoroutineScope)`**: Returns a `Flow` of events that occur after the given `StreamingToken`. This allows for continuous consumption of new events as they arrive.
15+
16+
A `StreamingToken` is an opaque marker that represents a specific position within the event stream, enabling consumers to resume event processing from a known point.
17+
18+
## `ExtendedQueryableStreamingEventSource` Interface
19+
20+
For more advanced querying capabilities, Krescent provides the `ExtendedQueryableStreamingEventSource` interface. It extends `StreamingEventSource` and adds methods such as:
21+
22+
- Querying events by a specific time range.
23+
- Fetching a specific event by its unique ID.
24+
25+
These capabilities are useful for scenarios requiring more targeted event retrieval beyond simple sequential streaming.
26+
27+
## `EventPublisher` Interface
28+
29+
Complementary to sourcing events, the `EventPublisher` interface is responsible for publishing new events into an event source. It typically provides methods to publish one or more events, which are then persisted and become available for consumption by `StreamingEventSource` implementations.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
title: Event Sourcing Strategies
3+
---
4+
5+
An `EventSourcingStrategy` in Krescent defines the specific approach for how events are fetched from a `StreamingEventSource` and subsequently processed by an `EventModel`. It dictates the lifecycle of event consumption for a model.
6+
7+
Krescent provides several common strategies to suit different use cases:
8+
9+
- **`CatchupSourcingStrategy`**: This strategy is designed to process all available historical events from the `StreamingEventSource` up to the current tail of the stream. Once all historical events have been fetched and processed, the strategy stops. This is typically used for building projections or read models that only need a snapshot of the current state based on past events.
10+
11+
- **`StreamingSourcingStrategy`**: This strategy first fetches all historical events, similar to `CatchupSourcingStrategy`. However, after processing the historical events, it continues to listen for and process new events as they arrive in the `StreamingEventSource`. This is suitable for live, continuously updating models that need to react to new information in real-time.
12+
13+
- **`NoSourcingStrategy`**: This strategy is used when an `EventModel` should not process any events from the source. Instead, it's typically used to restore a model to its initial empty state or to a previously saved checkpointed state without replaying events. This can be useful for initializing models or for scenarios where state is managed externally.
14+
15+
## `WriteCompatibleEventSourcingStrategy`
16+
17+
A `WriteCompatibleEventSourcingStrategy` is a marker interface indicating that the strategy is compatible with `WriteModelBase` instances. These strategies are suitable for models that not only consume events but also produce new events as a result of command processing. Both `CatchupSourcingStrategy` and `StreamingSourcingStrategy` can be write-compatible, allowing write models to build their state and then process commands that generate further events.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
title: Event Stream Processing
3+
---
4+
5+
Event stream processing in Krescent involves the continuous handling and transformation of sequences of events.
6+
7+
## `EventStreamProcessor` Interface
8+
9+
The core of event stream processing in Krescent is the `EventStreamProcessor` interface. This interface defines the fundamental contract for components that consume and process streams of events. Implementations of this interface are responsible for handling events as they arrive, performing computations, and potentially generating new events.
10+
11+
## `EventMessageStreamProcessor`
12+
13+
For processing raw event messages before they are deserialized into typed events, Krescent provides the `EventMessageStreamProcessor`. This processor operates on `EventMessage` objects, allowing for early-stage filtering, routing, or transformation based on message metadata or payload structure before the full deserialization cost is incurred.
14+
15+
## `TransformingModelEventProcessor`
16+
17+
The `TransformingModelEventProcessor` is a key component that leverages the `EventCatalog`. Its primary function is to:
18+
19+
1. **Deserialize**: Take an incoming `EventMessage` and use the `EventCatalog` to deserialize its payload into a specific, typed `Event` object.
20+
2. **Broadcast**: After successful deserialization, it broadcasts the typed `Event` to other interested downstream processors.
21+
22+
This processor acts as a bridge, converting raw event data into meaningful, domain-specific event objects.
23+
24+
## `BroadcastEventStreamProcessor`
25+
26+
The `BroadcastEventStreamProcessor` serves to distribute events to multiple downstream `EventStreamProcessor` instances. When an event is received by the `BroadcastEventStreamProcessor`, it forwards the event to all registered downstream processors, enabling parallel processing or fan-out scenarios. This is useful when multiple independent components need to react to the same event.

docs/concepts/events.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
---
2+
title: Events
3+
---
4+
5+
Events in Krescent are immutable facts that represent something that has happened in the system. They are the primary building blocks of Krescent's event-driven architecture.
6+
7+
## Base `Event` Class
8+
9+
All events in Krescent inherit from a base `Event` class. This class provides common functionality and a consistent structure for all events.
10+
11+
## `EventMetadata`
12+
13+
Every event carries metadata, which is encapsulated in the `EventMetadata` class. This metadata includes:
14+
15+
- **id**: A unique identifier for the event.
16+
- **type**: The type of the event.
17+
- **timestamp**: The time at which the event occurred.
18+
- **position**: The position of the event in the event stream.
19+
20+
## Physical vs. Virtual Events
21+
22+
Krescent distinguishes between two main types of events:
23+
24+
- **Physical Events**: These represent actual occurrences in the system, such as a user action or a sensor reading.
25+
- **`VirtualEvent`**: These are events that are derived or generated by the system itself, often as a result of processing physical events.
26+
27+
## `SystemEvent`
28+
29+
`SystemEvent`s are a special category of events used by Krescent for internal purposes. Some examples include:
30+
31+
- **`SystemStreamHeadEvent`**: Indicates the beginning of an event stream.
32+
- **`SystemStreamTailEvent`**: Indicates the end of an event stream.
33+
- **`SystemHintCommitTransactionEvent`**: Provides a hint to commit a transaction, often used in scenarios involving transactional event processing.
34+
35+
These system events help manage and coordinate the flow of events within Krescent.

0 commit comments

Comments
 (0)