Skip to content

Commit 8faa34e

Browse files
committed
added documentation on subscribing a projector to an eventstream
1 parent e91acd7 commit 8faa34e

File tree

1 file changed

+43
-0
lines changed

1 file changed

+43
-0
lines changed

_posts/2025-11-29-eventstore-projecting-events.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,49 @@ This enables:
284284
- **Controlled updates**: Process events in stages
285285
- **Testing**: Verify projection behavior at specific points
286286

287+
## Subscribing to Stream Updates
288+
289+
Instead of manually calling `run()` to update projections, you can subscribe a projector to automatically receive notifications when new events are appended. Simply include `subscribe()` in the builder chain:
290+
291+
```java
292+
CustomerSummary projection = new CustomerSummary("123");
293+
294+
Projector<CustomerEvent> projector = Projector.from(stream)
295+
.towards(projection)
296+
.subscribe()
297+
.build();
298+
299+
// New events automatically trigger projection updates
300+
stream.append(
301+
AppendCriteria.none(),
302+
Event.of(new CustomerRegistered("Alice"), Tags.of("customer", "123"))
303+
);
304+
305+
// The projection is updated asynchronously
306+
```
307+
308+
The `subscribe()` method configures the projector to register itself as an eventually consistent append listener on the stream. When events are appended, the projector's `eventsAppended()` method is invoked asynchronously, triggering a `run()` to process new events.
309+
310+
This subscription-based approach is ideal for keeping read models current with minimal latency. The projector automatically handles incremental updates, processing only events since its last run.
311+
312+
Combine subscriptions with bookmarking for resilience across restarts:
313+
314+
```java
315+
Projector<CustomerEvent> projector = Projector.from(stream)
316+
.towards(projection)
317+
.subscribe()
318+
.bookmarkProgress()
319+
.withReader("customer-summary")
320+
.readBeforeEachExecution()
321+
.done()
322+
.build();
323+
```
324+
325+
With this configuration:
326+
- **On startup**: The projector reads the bookmark and catches up to the current position
327+
- **During operation**: New appends trigger automatic incremental updates
328+
- **After each update**: The bookmark is saved, enabling seamless recovery
329+
287330
## Interpreting Metrics
288331

289332
The Projector returns `ProjectorMetrics` containing detailed statistics about projection execution:

0 commit comments

Comments
 (0)