Skip to content

Commit 9ff0986

Browse files
authored
[Docs] Add minor tweaks to migration guide 1/3 (#1763)
* Revise Policies, Retry * Add tldr and links at end of each section * Add tldr and links at end of each section * Add missing static keywords * Review extra empty lines * Fix linting * Apply suggestions from code review
1 parent 3403310 commit 9ff0986

File tree

4 files changed

+193
-129
lines changed

4 files changed

+193
-129
lines changed

docs/migration-v8.md

+126-68
Original file line numberDiff line numberDiff line change
@@ -37,56 +37,57 @@ These interfaces were created and used as shown below:
3737
<!-- snippet: migration-policies-v7 -->
3838
```cs
3939
// Create and use the ISyncPolicy.
40-
ISyncPolicy syncPolicy = Policy.Handle<Exception>().WaitAndRetry(3, _ => TimeSpan.FromSeconds(1));
40+
ISyncPolicy syncPolicy = Policy
41+
.Handle<Exception>()
42+
.WaitAndRetry(3, _ => TimeSpan.FromSeconds(1));
43+
4144
syncPolicy.Execute(() =>
4245
{
43-
// Your code here
46+
// Your code goes here
4447
});
4548

4649
// Create and use the IAsyncPolicy
47-
IAsyncPolicy asyncPolicy = Policy.Handle<Exception>().WaitAndRetryAsync(3, _ => TimeSpan.FromSeconds(1));
48-
await asyncPolicy.ExecuteAsync(
49-
async cancellationToken =>
50-
{
51-
// Your code here
52-
},
53-
cancellationToken);
50+
IAsyncPolicy asyncPolicy = Policy
51+
.Handle<Exception>()
52+
.WaitAndRetryAsync(3, _ => TimeSpan.FromSeconds(1));
53+
await asyncPolicy.ExecuteAsync(async token =>
54+
{
55+
// Your code goes here
56+
}, cancellationToken);
5457

5558
// Create and use the ISyncPolicy<T>
56-
ISyncPolicy<HttpResponseMessage> syncPolicyT = Policy
57-
.HandleResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode)
59+
ISyncPolicy<HttpResponseMessage> syncPolicyT = Policy<HttpResponseMessage>
60+
.HandleResult(result => !result.IsSuccessStatusCode)
5861
.WaitAndRetry(3, _ => TimeSpan.FromSeconds(1));
5962

6063
syncPolicyT.Execute(() =>
6164
{
62-
// Your code here
65+
// Your code goes here
6366
return GetResponse();
6467
});
6568

6669
// Create and use the IAsyncPolicy<T>
67-
IAsyncPolicy<HttpResponseMessage> asyncPolicyT = Policy
68-
.HandleResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode)
70+
IAsyncPolicy<HttpResponseMessage> asyncPolicyT = Policy<HttpResponseMessage>
71+
.HandleResult(result => !result.IsSuccessStatusCode)
6972
.WaitAndRetryAsync(3, _ => TimeSpan.FromSeconds(1));
70-
await asyncPolicyT.ExecuteAsync(
71-
async cancellationToken =>
72-
{
73-
// Your code here
74-
return await GetResponseAsync(cancellationToken);
75-
},
76-
cancellationToken);
73+
74+
await asyncPolicyT.ExecuteAsync(async token =>
75+
{
76+
// Your code goes here
77+
return await GetResponseAsync(token);
78+
}, cancellationToken);
7779
```
7880
<!-- endSnippet -->
7981

8082
### Configuring strategies in v8
8183

82-
In Polly v8, the previous code becomes:
84+
In Polly v8, there are no such interfaces. The previous samples become:
8385

8486
<!-- snippet: migration-policies-v8 -->
8587
```cs
8688
// Create and use the ResiliencePipeline.
8789
//
88-
// The ResiliencePipelineBuilder is used to start building the resilience pipeline,
89-
// instead of the static Policy.HandleException<TException>() call.
90+
// Use the ResiliencePipelineBuilder to start building the resilience pipeline
9091
ResiliencePipeline pipeline = new ResiliencePipelineBuilder()
9192
.AddRetry(new RetryStrategyOptions
9293
{
@@ -98,57 +99,64 @@ ResiliencePipeline pipeline = new ResiliencePipelineBuilder()
9899
.Build(); // After all necessary strategies are added, call Build() to create the pipeline.
99100
100101
// Synchronous execution
101-
pipeline.Execute(() =>
102+
pipeline.Execute(static () =>
102103
{
103-
// Your code here
104+
// Your code goes here
104105
});
105106

106107
// Asynchronous execution is also supported with the same pipeline instance
107-
await pipeline.ExecuteAsync(static async cancellationToken =>
108+
await pipeline.ExecuteAsync(static async token =>
108109
{
109-
// Your code here
110-
},
111-
cancellationToken);
110+
// Your code goes here
111+
}, cancellationToken);
112112

113113
// Create and use the ResiliencePipeline<T>.
114114
//
115115
// Building of generic resilience pipeline is very similar to non-generic one.
116-
// Notice the use of generic RetryStrategyOptions<HttpResponseMessage> to configure the strategy
117-
// as opposed to providing the arguments into the method.
116+
// Notice the use of generic RetryStrategyOptions<HttpResponseMessage> to configure the strategy.
118117
ResiliencePipeline<HttpResponseMessage> pipelineT = new ResiliencePipelineBuilder<HttpResponseMessage>()
119118
.AddRetry(new RetryStrategyOptions<HttpResponseMessage>
120119
{
121120
ShouldHandle = new PredicateBuilder<HttpResponseMessage>()
122121
.Handle<Exception>()
123-
.HandleResult(result => !result.IsSuccessStatusCode),
122+
.HandleResult(static result => !result.IsSuccessStatusCode),
124123
Delay = TimeSpan.FromSeconds(1),
125124
MaxRetryAttempts = 3,
126125
BackoffType = DelayBackoffType.Constant
127126
})
128127
.Build();
129128

130129
// Synchronous execution
131-
pipelineT.Execute(() =>
130+
pipelineT.Execute(static () =>
132131
{
133-
// Your code here
132+
// Your code goes here
134133
return GetResponse();
135134
});
136135

137136
// Asynchronous execution
138-
await pipelineT.ExecuteAsync(static async cancellationToken =>
137+
await pipelineT.ExecuteAsync(static async token =>
139138
{
140-
// Your code here
141-
return await GetResponseAsync(cancellationToken);
142-
},
143-
cancellationToken);
139+
// Your code goes here
140+
return await GetResponseAsync(token);
141+
}, cancellationToken);
144142
```
145143
<!-- endSnippet -->
146144

145+
> [!IMPORTANT]
146+
>
147+
> Things to remember:
148+
>
149+
> - Use `ResiliencePipelineBuilder{<TResult>}` to build a resiliency pipeline
150+
> - Use one of the `Add*` builder methods to add a new strategy to the pipeline
151+
> - Use either `Execute` or `ExecuteAsync` depending on the execution context
152+
>
153+
> For further information please check out the [Resilience pipelines documentation](pipelines/index.md).
154+
147155
## Migrating policy wrap
148156

149157
### Policy wrap in v7
150158

151-
Policy wrap is used to combine multiple policies into one as shown in the v7 example below:
159+
Policy wrap is used to combine multiple policies into one:
152160

153161
<!-- snippet: migration-policy-wrap-v7 -->
154162
```cs
@@ -165,7 +173,7 @@ IAsyncPolicy wrappedPolicy = Policy.WrapAsync(retryPolicy, timeoutPolicy);
165173

166174
### Policy wrap in v8
167175

168-
In v8, there's no need to use policy wrap explicitly. Instead, policy wrapping is integrated into `ResiliencePipelineBuilder`, as shown in the example below:
176+
In v8, there's no need to use policy wrap explicitly. Instead, policy wrapping is integrated into `ResiliencePipelineBuilder`:
169177

170178
<!-- snippet: migration-policy-wrap-v8 -->
171179
```cs
@@ -185,12 +193,20 @@ ResiliencePipeline pipeline = new ResiliencePipelineBuilder()
185193
```
186194
<!-- endSnippet -->
187195

188-
> [!NOTE]
189-
> See [fallback after retries](strategies/fallback.md#fallback-after-retries) for an example on how the strategies are executed.
196+
See [fallback after retries](strategies/fallback.md#fallback-after-retries) for an example on how the strategies are executed.
197+
198+
> [!IMPORTANT]
199+
>
200+
> Things to remember:
201+
>
202+
> - Use `ResiliencePipelineBuilder{<TResult>}` to build a resiliency pipeline
203+
> - Use multiple `Add*` builder methods to add new strategies to your pipeline
204+
>
205+
> For further information please check out the [Resilience pipelines documentation](pipelines/index.md).
190206
191207
## Migrating retry policies
192208

193-
This section describes how to migrate the v7 retry policy to a resilience strategy in v8.
209+
This section describes how to migrate v7 retry policies to V8 retry strategies.
194210

195211
### Retry in v7
196212

@@ -200,13 +216,13 @@ In v7 the retry policy is configured as:
200216
```cs
201217
// Retry once
202218
Policy
203-
.Handle<SomeExceptionType>()
204-
.Retry();
219+
.Handle<SomeExceptionType>()
220+
.Retry();
205221

206222
// Retry multiple times
207223
Policy
208-
.Handle<SomeExceptionType>()
209-
.Retry(3);
224+
.Handle<SomeExceptionType>()
225+
.Retry(3);
210226

211227
// Retry multiple times with callback
212228
Policy
@@ -215,6 +231,11 @@ Policy
215231
{
216232
// Add logic to be executed before each retry, such as logging
217233
});
234+
235+
// Retry forever
236+
Policy
237+
.Handle<SomeExceptionType>()
238+
.RetryForever();
218239
```
219240
<!-- endSnippet -->
220241

@@ -254,7 +275,7 @@ new ResiliencePipelineBuilder().AddRetry(new RetryStrategyOptions
254275
ShouldHandle = new PredicateBuilder().Handle<SomeExceptionType>(),
255276
MaxRetryAttempts = 3,
256277
Delay = TimeSpan.Zero,
257-
OnRetry = args =>
278+
OnRetry = static args =>
258279
{
259280
// Add logic to be executed before each retry, such as logging
260281
return default;
@@ -278,15 +299,10 @@ new ResiliencePipelineBuilder().AddRetry(new RetryStrategyOptions
278299

279300
<!-- snippet: migration-retry-wait-v7 -->
280301
```cs
281-
// Retry forever
282-
Policy
283-
.Handle<SomeExceptionType>()
284-
.WaitAndRetryForever(_ => TimeSpan.FromSeconds(1));
285-
286302
// Wait and retry multiple times
287303
Policy
288-
.Handle<SomeExceptionType>()
289-
.WaitAndRetry(3, _ => TimeSpan.FromSeconds(1));
304+
.Handle<SomeExceptionType>()
305+
.WaitAndRetry(3, _ => TimeSpan.FromSeconds(1));
290306

291307
// Wait and retry multiple times with callback
292308
Policy
@@ -324,7 +340,7 @@ new ResiliencePipelineBuilder().AddRetry(new RetryStrategyOptions
324340
MaxRetryAttempts = 3,
325341
Delay = TimeSpan.FromSeconds(1),
326342
BackoffType = DelayBackoffType.Constant,
327-
OnRetry = args =>
343+
OnRetry = static args =>
328344
{
329345
// Add logic to be executed before each retry, such as logging
330346
return default;
@@ -350,9 +366,9 @@ new ResiliencePipelineBuilder().AddRetry(new RetryStrategyOptions
350366
```cs
351367
// Wait and retry with result handling
352368
Policy
353-
.Handle<SomeExceptionType>()
354-
.OrResult<HttpResponseMessage>(response => response.StatusCode == HttpStatusCode.InternalServerError)
355-
.WaitAndRetry(3, _ => TimeSpan.FromSeconds(1));
369+
.Handle<SomeExceptionType>()
370+
.OrResult<HttpResponseMessage>(result => result.StatusCode == HttpStatusCode.InternalServerError)
371+
.WaitAndRetry(3, _ => TimeSpan.FromSeconds(1));
356372
```
357373
<!-- endSnippet -->
358374

@@ -366,7 +382,7 @@ new ResiliencePipelineBuilder<HttpResponseMessage>().AddRetry(new RetryStrategyO
366382
// PredicateBuilder is a convenience API that can used to configure the ShouldHandle predicate.
367383
ShouldHandle = new PredicateBuilder<HttpResponseMessage>()
368384
.Handle<SomeExceptionType>()
369-
.HandleResult(result => result.StatusCode == HttpStatusCode.InternalServerError),
385+
.HandleResult(static result => result.StatusCode == HttpStatusCode.InternalServerError),
370386
MaxRetryAttempts = 3,
371387
})
372388
.Build();
@@ -376,7 +392,7 @@ new ResiliencePipelineBuilder<HttpResponseMessage>().AddRetry(new RetryStrategyO
376392
{
377393
// Determine what results to retry using switch expressions.
378394
// Note that PredicateResult.True() is just a shortcut for "new ValueTask<bool>(true)".
379-
ShouldHandle = args => args.Outcome switch
395+
ShouldHandle = static args => args.Outcome switch
380396
{
381397
{ Exception: SomeExceptionType } => PredicateResult.True(),
382398
{ Result: { StatusCode: HttpStatusCode.InternalServerError } } => PredicateResult.True(),
@@ -388,7 +404,14 @@ new ResiliencePipelineBuilder<HttpResponseMessage>().AddRetry(new RetryStrategyO
388404
```
389405
<!-- endSnippet -->
390406

391-
It's important to remember that the configuration in v8 is options based, i.e. `RetryStrategyOptions` are used.
407+
> [!IMPORTANT]
408+
>
409+
> Things to remember:
410+
>
411+
> - Use `AddRetry` to add a retry strategy to your resiliency pipeline
412+
> - Use the `RetryStrategyOptions` to customize your retry behavior to meet your requirements
413+
>
414+
> For further information please check out the [Retry resilience strategy documentation](strategies/retry.md).
392415
393416
## Migrating rate limit policies
394417

@@ -452,6 +475,15 @@ ResiliencePipeline<HttpResponseMessage> pipelineT = new ResiliencePipelineBuilde
452475
```
453476
<!-- endSnippet -->
454477

478+
> [!IMPORTANT]
479+
>
480+
> Things to remember:
481+
>
482+
> - Use `AddRateLimiter` to add a rate limiter strategy to your resiliency pipeline
483+
> - Use one of the derived classes of [`ReplenishingRateLimiter`](https://learn.microsoft.com/dotnet/api/system.threading.ratelimiting.replenishingratelimiter) to customize your rate limiter behavior to meet your requirements
484+
>
485+
> For further information please check out the [Rate limiter resilience strategy documentation](strategies/rate-limiter.md).
486+
455487
## Migrating bulkhead policies
456488

457489
The bulkhead policy is now replaced by the [rate limiter strategy](strategies/rate-limiter.md) which uses the [`System.Threading.RateLimiting`](https://www.nuget.org/packages/System.Threading.RateLimiting) package. The new counterpart to bulkhead is `ConcurrencyLimiter`.
@@ -464,16 +496,24 @@ The bulkhead policy is now replaced by the [rate limiter strategy](strategies/ra
464496
<!-- snippet: migration-bulkhead-v7 -->
465497
```cs
466498
// Create sync bulkhead
467-
ISyncPolicy syncPolicy = Policy.Bulkhead(maxParallelization: 100, maxQueuingActions: 50);
499+
ISyncPolicy syncPolicy = Policy.Bulkhead(
500+
maxParallelization: 100,
501+
maxQueuingActions: 50);
468502

469503
// Create async bulkhead
470-
IAsyncPolicy asyncPolicy = Policy.BulkheadAsync(maxParallelization: 100, maxQueuingActions: 50);
504+
IAsyncPolicy asyncPolicy = Policy.BulkheadAsync(
505+
maxParallelization: 100,
506+
maxQueuingActions: 50);
471507

472508
// Create generic sync bulkhead
473-
ISyncPolicy<HttpResponseMessage> syncPolicyT = Policy.Bulkhead<HttpResponseMessage>(maxParallelization: 100, maxQueuingActions: 50);
509+
ISyncPolicy<HttpResponseMessage> syncPolicyT = Policy.Bulkhead<HttpResponseMessage>(
510+
maxParallelization: 100,
511+
maxQueuingActions: 50);
474512

475513
// Create generic async bulkhead
476-
IAsyncPolicy<HttpResponseMessage> asyncPolicyT = Policy.BulkheadAsync<HttpResponseMessage>(maxParallelization: 100, maxQueuingActions: 50);
514+
IAsyncPolicy<HttpResponseMessage> asyncPolicyT = Policy.BulkheadAsync<HttpResponseMessage>(
515+
maxParallelization: 100,
516+
maxQueuingActions: 50);
477517
```
478518
<!-- endSnippet -->
479519

@@ -498,6 +538,15 @@ ResiliencePipeline<HttpResponseMessage> pipelineT = new ResiliencePipelineBuilde
498538
```
499539
<!-- endSnippet -->
500540

541+
> [!IMPORTANT]
542+
>
543+
> Things to remember:
544+
>
545+
> - Use `AddConcurrencyLimiter` to add a concurrency limiter strategy to your resiliency pipeline
546+
> - Use the `ConcurrencyLimiterOptions` to customize your concurrency limiter behavior to meet your requirements
547+
>
548+
> For further information please check out the [Rate limiter resilience strategy documentation](strategies/rate-limiter.md).
549+
501550
## Migrating timeout policies
502551

503552
> [!NOTE]
@@ -539,6 +588,15 @@ ResiliencePipeline<HttpResponseMessage> pipelineT = new ResiliencePipelineBuilde
539588
```
540589
<!-- endSnippet -->
541590

591+
> [!IMPORTANT]
592+
>
593+
> Things to remember:
594+
>
595+
> - Use `AddTimeout` to add a timeout strategy to your resiliency pipeline
596+
> - Use the `TimeoutStrategyOptions` to customize your timeout behavior to meet your requirements
597+
>
598+
> For further information please check out the [Timeout resilience strategy documentation](strategies/timeout.md).
599+
542600
## Migrating other policies
543601

544602
Migrating is a process similar to the ones described in the previous sections. Keep in mind that:

0 commit comments

Comments
 (0)