Add store-agnostic projection dead-letter count read to IEventDatabase (#356)#363
Merged
Merged
Conversation
#356) JasperFx.Events 2.0 made SkipApplyErrors the default, so accumulating DeadLetterEvent rows is now the primary "projection unhealthy" signal — but IEventDatabase only let consumers *write* dead letters, forcing store-specific, reflection-based reads. Adds two read members to IEventDatabase: - CountDeadLetterEventsAsync(ShardName, CancellationToken) — per-shard count - FetchDeadLetterCountsAsync(CancellationToken) — bulk, one DeadLetterShardCount (ProjectionName, ShardKey, Count) per shard, mirroring AllProjectionProgress Both ship with default interface implementations returning 0 / empty as a stand-in, so existing IEventDatabase implementers keep compiling and behave gracefully until they override. Marten (JasperFx/marten#4546) and Polecat (JasperFx/polecat#146) will provide real implementations. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 23, 2026
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #356.
What changed
Adds a store-agnostic way to read projection/subscription dead-letter counts to
JasperFx.Events.IEventDatabase:DeadLetterShardCountis keyed to align withShardName.Name(ProjectionName) andShardName.ShardKey(ShardKey), matching howDeadLetterEventrecords them.FetchDeadLetterCountsAsyncmirrors the "give me every row" shape of the existingAllProjectionProgress.Default stand-in implementations
Both members ship with default interface implementations that return
0/ an empty list, so:IEventDatabaseimplementers keep compiling with no changes, andGetServices<IEventDatabase>()) get a graceful no-op until a store implements the real read.Real implementations are tracked in JasperFx/marten#4546 (Marten —
DeadLetterEventis already a stored document) and JasperFx/polecat#146 (Polecat — note its dead-letter storage is currently a no-op, so it needs storage first).Why
JasperFx.Events 2.0 made
SkipApplyErrors = truethe default: a failedApply()is recorded as aDeadLetterEventand the shard keeps advancing, so accumulating dead-letter rows is the primary "this projection is unhealthy" signal. Until now the abstraction only let you write them.Tests
EventTests/Daemon/DeadLetterCountDefaultsTests— a bareIEventDatabasethat overrides neither new member; the calls exercise the default stand-ins and assert0/ empty (green on net9.0 + net10.0).