Conversation
mgravell
marked this pull request as ready for review
March 16, 2026 11:30
uglide
reviewed
Jul 8, 2026
uglide
left a comment
Contributor
There was a problem hiding this comment.
The main missing peaces at this stage:
- Circuit breaker/Failure detector on the organic load
- Retries
- Per-member health checks
- Limited configuratbility and deviations in the default values (see inline comments)
* move things around and write core * bucket logic * buildable * nit * add unit tests * end-to-end tests * docs * improve circuit-breaker reactivity * gate health-checks, since it can now run concurrently due to circuit-breaker * end-to-end tests
- fix public API for updated lib
* start dedup core * find classes * start stubbing class * successfully stub out all methods (it compiles!) * stub out execute and tuples * generalize mutator API to include channels * wip * fundamentals: compile (untested) * I *think* this is the core retry logic! * nit * fix build * iterating on RetryPolicy * nits * start command categorization * cleanup API * duplicate .Database into IDatabaseAsync (from IDatabase) * unit tests * end to end test, but it highlights a design fault * retry logic * nits * end-to-end tests * docs * namespace
* Add retryable transactions to WithRetry Introduces a retryable transaction, obtained via WithRetry(...).CreateTransaction(). Mechanism: RetryTransaction is an [AutoDatabase] recorder. The generator funnels each builder call into (state, projection) - the same captured unit RetryDatabase replays - which RetryTransaction records while handing the caller a durable, still-incomplete proxy task. ExecuteAsync runs the retry loop: each attempt spins up a fresh one-shot inner transaction against the underlying database (for multi-group this resolves the currently active member, so a retry after failover lands on the new member), replays the recorded ops and constraints onto it, and awaits it. On clean completion the per-attempt outcomes are forwarded onto the durable proxies; on a transient fault the attempt is discarded and replayed; on terminal failure the proxies are faulted. The transaction's effective retry category is the most side-effecting of its operations (WATCH constraints excluded); it is injected onto the EXEC flags so the resulting fault carries it and the shared RetryPolicy/FaultContext gating applies exactly as for a single command. Retry policy math is extracted into a shared RetryController used by both RetryDatabase and RetryTransaction. Surface (all [Experimental] SER007): - new ITransactionAsync (async-only transaction; sibling of ITransaction, no shipped-API change) - new IRetryDatabase with CreateTransaction; WithRetry now returns it - RedisTransaction/KeyPrefixedTransaction also implement ITransactionAsync Includes end-to-end tests: rides out a transient EXEC failure, respects the aggregate category gate, and does not double-apply a discarded attempt. * Move CreateTransaction onto IDatabaseAsync Reworks the retryable-transaction surface so WithRetry keeps returning IDatabaseAsync and RetryDatabase never has to implement IDatabase (which would drag in the sync surface). CreateTransaction now lives on IDatabaseAsync, returning the async-only ITransactionAsync; IDatabase.CreateTransaction refines the return type to ITransaction via "new", with ITransaction : IBatch, ITransactionAsync. To avoid any ambiguity, ITransaction re-declares AddCondition/ExecuteAsync(flags) with "new" rather than relying on inheritance, so its surface is self-contained and its shipped-API lines are unchanged. - IDatabaseAsync gains CreateTransaction(): ITransactionAsync ([Experimental] SER007) - IDatabase.CreateTransaction is now "new ITransaction ..." (signature unchanged) - ITransaction : IBatch, ITransactionAsync (re-declares its two async members) - the source generator skips CreateTransaction/CreateBatch (not replayable round-trips) - explicit IDatabaseAsync.CreateTransaction bridges on RedisDatabase, MultiGroupDatabase, KeyPrefixedDatabase; KeyPrefixed<TInner> base throws (reimplemented by the database); RetryTransaction throws (nested) - WithRetry returns IDatabaseAsync again; IRetryDatabase removed All retry/transaction/batch/keyprefix tests pass; full Release build across all TFMs. * Make ITransactionAsync stable (drop [Experimental]) ITransaction (stable) derives from ITransactionAsync, so the type must be stable too; the experimental gating stays on IDatabaseAsync.CreateTransaction (the new entry point). Also drops the now-redundant explicit ITransactionAsync from RedisTransaction and KeyPrefixedTransaction (implied by ITransaction : ITransactionAsync). * Drop IDatabase requirement from retry transaction Now that CreateTransaction is on IDatabaseAsync, RetryTransaction only needs an IDatabaseAsync source: it creates each attempt's transaction via source.CreateTransaction() and uses only AddCondition/ExecuteAsync (both on ITransactionAsync). Removes the IDatabase cast and its NotSupportedException path, so WithRetry(...).CreateTransaction() works over any IDatabaseAsync.
# Conflicts: # src/StackExchange.Redis/PublicAPI/PublicAPI.Shipped.txt # src/StackExchange.Redis/PublicAPI/PublicAPI.Unshipped.txt
…appy - step up the obsolete member removal
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.
and batchesdiscussion topics / follow up items: