Skip to content

Commit 121a41a

Browse files
committed
intermediate broken
1 parent 2c6bce1 commit 121a41a

22 files changed

+890
-888
lines changed

StackExchange.Redis.sln

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -103,31 +103,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{00CA0876-DA9
103103
EndProject
104104
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "toys", "toys", "{E25031D3-5C64-430D-B86F-697B66816FD8}"
105105
EndProject
106-
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{153A10E4-E668-41AD-9E0F-6785CE7EED66}"
107-
ProjectSection(SolutionItems) = preProject
108-
docs\Basics.md = docs\Basics.md
109-
docs\Configuration.md = docs\Configuration.md
110-
docs\Events.md = docs\Events.md
111-
docs\ExecSync.md = docs\ExecSync.md
112-
docs\index.md = docs\index.md
113-
docs\KeysScan.md = docs\KeysScan.md
114-
docs\KeysValues.md = docs\KeysValues.md
115-
docs\PipelinesMultiplexers.md = docs\PipelinesMultiplexers.md
116-
docs\Profiling.md = docs\Profiling.md
117-
docs\Profiling_v1.md = docs\Profiling_v1.md
118-
docs\Profiling_v2.md = docs\Profiling_v2.md
119-
docs\PubSubOrder.md = docs\PubSubOrder.md
120-
docs\ReleaseNotes.md = docs\ReleaseNotes.md
121-
docs\Resp3.md = docs\Resp3.md
122-
docs\RespLogging.md = docs\RespLogging.md
123-
docs\Scripting.md = docs\Scripting.md
124-
docs\Server.md = docs\Server.md
125-
docs\Testing.md = docs\Testing.md
126-
docs\ThreadTheft.md = docs\ThreadTheft.md
127-
docs\Timeouts.md = docs\Timeouts.md
128-
docs\Transactions.md = docs\Transactions.md
129-
EndProjectSection
130-
EndProject
131106
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestConsoleBaseline", "toys\TestConsoleBaseline\TestConsoleBaseline.csproj", "{D58114AE-4998-4647-AFCA-9353D20495AE}"
132107
EndProject
133108
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = ".github", ".github\.github.csproj", "{8FB98E7D-DAE2-4465-BD9A-104000E0A2D4}"
@@ -144,6 +119,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleTestBaseline", "test
144119
EndProject
145120
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimpleCancellationDemo", "tests\SimpleCancellationDemo\SimpleCancellationDemo.csproj", "{368A06AA-9DEB-4C55-B9CF-A1070B85E502}"
146121
EndProject
122+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "docs", "docs\docs.csproj", "{64CF03B6-6B29-4C4C-88B8-7B9E317D631A}"
123+
EndProject
147124
Global
148125
GlobalSection(SolutionConfigurationPlatforms) = preSolution
149126
Debug|Any CPU = Debug|Any CPU
@@ -198,6 +175,10 @@ Global
198175
{368A06AA-9DEB-4C55-B9CF-A1070B85E502}.Debug|Any CPU.Build.0 = Debug|Any CPU
199176
{368A06AA-9DEB-4C55-B9CF-A1070B85E502}.Release|Any CPU.ActiveCfg = Release|Any CPU
200177
{368A06AA-9DEB-4C55-B9CF-A1070B85E502}.Release|Any CPU.Build.0 = Release|Any CPU
178+
{64CF03B6-6B29-4C4C-88B8-7B9E317D631A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
179+
{64CF03B6-6B29-4C4C-88B8-7B9E317D631A}.Debug|Any CPU.Build.0 = Debug|Any CPU
180+
{64CF03B6-6B29-4C4C-88B8-7B9E317D631A}.Release|Any CPU.ActiveCfg = Release|Any CPU
181+
{64CF03B6-6B29-4C4C-88B8-7B9E317D631A}.Release|Any CPU.Build.0 = Release|Any CPU
201182
EndGlobalSection
202183
GlobalSection(SolutionProperties) = preSolution
203184
HideSolutionNode = FALSE
@@ -215,7 +196,6 @@ Global
215196
{D082703F-1652-4C35-840D-7D377F6B9979} = {96E891CD-2ED7-4293-A7AB-4C6F5D8D2B05}
216197
{8375813E-FBAF-4DA3-A2C7-E4645B39B931} = {E25031D3-5C64-430D-B86F-697B66816FD8}
217198
{3DA1EEED-E9FE-43D9-B293-E000CFCCD91A} = {E25031D3-5C64-430D-B86F-697B66816FD8}
218-
{153A10E4-E668-41AD-9E0F-6785CE7EED66} = {3AD17044-6BFF-4750-9AC2-2CA466375F2A}
219199
{D58114AE-4998-4647-AFCA-9353D20495AE} = {E25031D3-5C64-430D-B86F-697B66816FD8}
220200
{A9F81DA3-DA82-423E-A5DD-B11C37548E06} = {96E891CD-2ED7-4293-A7AB-4C6F5D8D2B05}
221201
{A0F89B8B-32A3-4C28-8F1B-ADE343F16137} = {73A5C363-CA1F-44C4-9A9B-EF791A76BA6A}

docs/AmbientCancellation.md

Lines changed: 0 additions & 195 deletions
This file was deleted.

docs/CancellationTimeout.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Ambient Cancellation Support
2+
3+
StackExchange.Redis supports cancellation / timeout of operations. Because this feature impacts all operations, rather than add new parameters
4+
to every method, it uses a declarative scope - an "ambient" context. This uses the `AsyncLocal<T>` feature, allowing for meaning:
5+
6+
- unrelated code-paths (threads or async-contexts) can have different values without conflicting with each-other
7+
- the value is correctly propagated between `async`/`await` code
8+
9+
## Usage
10+
11+
### Timeout
12+
13+
Timeouts are probably the most common cancellation scenario, so is exposed directly:
14+
15+
```csharp
16+
using (database.Multiplexer.WithTimeout(TimeSpan.FromSeconds(5)))
17+
// using (database.WithTimeout(5000)) // identical
18+
{
19+
await database.StringSetAsync("key", "value");
20+
var value = await database.StringGetAsync("key");
21+
// operations will be cancelled when the *combined* time (i.e. from the `WithTimeout` call) exceeds 5 seconds
22+
}
23+
```
24+
25+
### Cancellation
26+
27+
You can also use `CancellationToken` to drive cancellation:
28+
29+
```csharp
30+
CancellationToken token = ...; // for example, from HttpContext.RequestAborted
31+
using (database.Multiplexer.WithCancellation(token))
32+
{
33+
await database.StringSetAsync("key", "value");
34+
var value = await database.StringGetAsync("key");
35+
// both operations use the cancellation token
36+
}
37+
```
38+
### Combined Cancellation and Timeout
39+
40+
These two concepts can be combined:
41+
42+
```csharp
43+
44+
45+
using (database.Multiplexer.WithCancellationAndTimeout(yourToken, TimeSpan.FromSeconds(10)))
46+
{
47+
await database.StringSetAsync("key", "value");
48+
var value = await database.StringGetAsync("key");
49+
// operations use the cancellation token *and* observe the specified timeout
50+
}
51+
```
52+
53+
### Nested Scopes
54+
55+
Timeout/cancellation scopes can be nested, with the inner scope *replacing* the outer scope for that database:
56+
57+
```csharp
58+
using (database.Multiplexer.WithCancellation(yourToken))
59+
{
60+
await database.StringSetAsync("key1", "value1"); // Uses yourToken
61+
62+
using (database.Multiplexer.WithTimeout(5000))
63+
{
64+
await database.StringSetAsync("key2", "value2"); // Uses 5s timeout, but does *not* observe yourToken
65+
}
66+
67+
await database.StringSetAsync("key3", "value3"); // Uses yourToken
68+
}
69+
```
70+
71+
Consequently, timeout/cancellation can be suppressed by using `.WithCancellation(CancellationToken.None)`.
72+
73+
## Multiplexer scope
74+
75+
The scope of a `WithTimeout` (etc) call is tied to the *multiplexer*, hence the typical usage of `database.Multiplexer.WithTimeout(...)`.
76+
Usually, there is only a single multiplexer in use, but this choice ensures that there are no surprises by library code outside of
77+
your control / knowledge being impacted by your local cancellation / timeout choices.

docs/docs.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<Project Sdk="Microsoft.Build.NoTargets/3.3.0">
2+
<!-- this is actually here just to serve as a hub for docs, so we don't need to keep editing the sln-->
3+
<PropertyGroup>
4+
<TargetFramework>netstandard2.0</TargetFramework>
5+
</PropertyGroup>
6+
</Project>

0 commit comments

Comments
 (0)