Intial spike of ambient cancellation by mgravell · Pull Request #2908 · StackExchange/StackExchange.Redis
After consideration, I have decided not to proceed with this PR; there is significant complexity and confusion and potential performance impact, when a simpler version of things can already be achieved, at least on .NET 6+, with the inbuilt .WaitAsync(...) method family:
var timeout = TimeSpan.FromSeconds(5); var cancellationToken = ...; await db.StringSetAsync(key, value).WaitAsync(timeout); var val = await db.StringGetAsync(key).WaitAsync(cancellationToken);
This approach also has additional flexibility advantages. The downside is that we don't withdraw the command from the unsent queue. I think, on reflection, that I can live with that for the simplicity.
A separate PR will be issued with guidance on using this approach.
(status: in progress; first draft is via generative codegen, to be reviewed, validated and expanded)
Implement async cancellation (also encompasses per-command cancellation).
Design approach here is to use ambient async state (i.e. AsyncLocal<T>) via wrapper layers:
- exposing directly on individual methods is horrible due to API explosion / maintenance burden
- decorator wrapper isn't really viable because there would be no proper way for the decorated API to pass the value down
Final API approach can be summarized as:
using (database.WithCancellation(someToken)) // alternative: using (database.WithTimeout(timeout)) { await database.DoTheThingAsync(...); }
The return from WithCancellation here is an IDisposable that simply restores the previous state; it is not a decorated database. I view this as a positive, as it avoids the fat-fingered error (if it was that style of API) that is too common with the transaction API:
using var withTimeout = database.WithCancellation(someToken); await database.DoTheThingAsync(...); // ^^^ ERROR: should be await withTimeout.DoTheThingAsync(...);
This currently only applies to async operations, but it is an interesting question as to whether this also work for synchronous operations. It ... isn't impossible.