Skip to content

Commit f7d434a

Browse files
authored
[Docs] Add sequence diagrams to fallback, retry, and rate limiter (#1702)
Add diagrams to fallback, retry, and rate limiter.
1 parent 940c628 commit f7d434a

File tree

4 files changed

+237
-10
lines changed

4 files changed

+237
-10
lines changed

docs/strategies/fallback.md

+39
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,45 @@ new ResiliencePipelineBuilder<UserAvatar>()
6565
| `FallbackAction` | `Null`, **Required** | Fallback action to be executed. |
6666
| `OnFallback` | `null` | Event that is raised when fallback happens. |
6767

68+
## Diagrams
69+
70+
### Happy path sequence diagram
71+
72+
```mermaid
73+
%%{init: {'theme':'dark'}}%%
74+
sequenceDiagram
75+
actor C as Caller
76+
participant P as Pipeline
77+
participant F as Fallback
78+
participant D as DecoratedUserCallback
79+
80+
C->>P: Calls ExecuteAsync
81+
P->>F: Calls ExecuteCore
82+
F->>+D: Invokes
83+
D->>-F: Returns result
84+
F->>P: Returns result
85+
P->>C: Returns result
86+
```
87+
88+
### Unhappy path sequence diagram
89+
90+
```mermaid
91+
%%{init: {'theme':'dark'}}%%
92+
sequenceDiagram
93+
actor C as Caller
94+
participant P as Pipeline
95+
participant F as Fallback
96+
participant D as DecoratedUserCallback
97+
98+
C->>P: Calls ExecuteAsync
99+
P->>F: Calls ExecuteCore
100+
F->>+D: Invokes
101+
D->>-F: Fails
102+
F->>F: Falls back to<br/>substitute result
103+
F->>P: Returns <br/>substituted result
104+
P->>C: Returns <br/>substituted result
105+
```
106+
68107
## Patterns
69108

70109
### Fallback after retries

docs/strategies/rate-limiter.md

+134
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,140 @@ catch (RateLimiterRejectedException ex)
7474
| `DefaultRateLimiterOptions` | `PermitLimit` set to 1000 and `QueueLimit` set to 0. | The options for the default concurrency limiter that will be used when `RateLimiter` is `null`. |
7575
| `OnRejected` | `null` | Event that is raised when the execution is rejected by the rate limiter. |
7676

77+
## Diagrams
78+
79+
### Rate Limiter
80+
81+
Let's suppose we have a rate limiter strategy with `PermitLimit` : `1` and `Window` : `10 seconds`.
82+
83+
### Rate Limiter: happy path sequence diagram
84+
85+
```mermaid
86+
%%{init: {'theme':'dark'}}%%
87+
sequenceDiagram
88+
actor C as Caller
89+
participant P as Pipeline
90+
participant RL as RateLimiter
91+
participant D as DecoratedUserCallback
92+
93+
C->>P: Calls ExecuteAsync
94+
P->>RL: Calls ExecuteCore
95+
Note over RL,D: Window start
96+
RL->>+D: Invokes
97+
D->>-RL: Returns result
98+
RL->>P: Returns result
99+
P->>C: Returns result
100+
Note over C: Several seconds later...
101+
Note over RL,D: Window end
102+
C->>P: Calls ExecuteAsync
103+
P->>RL: Calls ExecuteCore
104+
Note over RL,D: Window start
105+
RL->>+D: Invokes
106+
D->>-RL: Returns result
107+
RL->>P: Returns result
108+
P->>C: Returns result
109+
Note over RL,D: Window end
110+
```
111+
112+
#### Rate limiter: unhappy path sequence diagram
113+
114+
```mermaid
115+
%%{init: {'theme':'dark'}}%%
116+
sequenceDiagram
117+
actor C as Caller
118+
participant P as Pipeline
119+
participant RL as RateLimiter
120+
participant D as DecoratedUserCallback
121+
122+
C->>P: Calls ExecuteAsync
123+
P->>RL: Calls ExecuteCore
124+
Note over RL,D: Window start
125+
RL->>+D: Invokes
126+
D->>-RL: Returns result
127+
RL->>P: Returns result
128+
P->>C: Returns result
129+
Note over C: Few seconds later...
130+
C->>P: Calls ExecuteAsync
131+
P->>RL: Calls ExecuteCore
132+
RL->>RL: Rejects request
133+
RL->>P: Throws <br/>RateLimiterRejectedException
134+
P->>C: Propagates exception
135+
Note over RL,D: Window end
136+
```
137+
138+
### Concurrency Limiter
139+
140+
Let's suppose we have a concurrency limiter strategy with `PermitLimit` : `1` and `QueueLimit` : `1`.
141+
142+
#### Concurrency limiter: happy path sequence diagram
143+
144+
```mermaid
145+
%%{init: {'theme':'dark'}}%%
146+
sequenceDiagram
147+
actor C1 as Caller1
148+
actor C2 as Caller2
149+
participant P as Pipeline
150+
participant CL as ConcurrencyLimiter
151+
participant D as DecoratedUserCallback
152+
153+
par
154+
C1->>P: Calls ExecuteAsync
155+
and
156+
C2->>P: Calls ExecuteAsync
157+
end
158+
159+
P->>CL: Calls ExecuteCore
160+
CL->>+D: Invokes (C1)
161+
P->>CL: Calls ExecuteCore
162+
CL->>CL: Queues request
163+
164+
D->>-CL: Returns result (C1)
165+
CL->>P: Returns result (C1)
166+
CL->>+D: Invokes (C2)
167+
P->>C1: Returns result
168+
D->>-CL: Returns result (C2)
169+
CL->>P: Returns result (C2)
170+
P->>C2: Returns result
171+
```
172+
173+
#### Concurrency Limiter: unhappy path sequence diagram
174+
175+
```mermaid
176+
%%{init: {'theme':'dark'}}%%
177+
sequenceDiagram
178+
actor C1 as Caller1
179+
actor C2 as Caller2
180+
actor C3 as Caller3
181+
participant P as Pipeline
182+
participant CL as ConcurrencyLimiter
183+
participant D as DecoratedUserCallback
184+
185+
par
186+
C1->>P: Calls ExecuteAsync
187+
and
188+
C2->>P: Calls ExecuteAsync
189+
and
190+
C3->>P: Calls ExecuteAsync
191+
end
192+
193+
P->>CL: Calls ExecuteCore
194+
CL->>+D: Invokes (C1)
195+
P->>CL: Calls ExecuteCore
196+
CL->>CL: Queues request (C2)
197+
P->>CL: Calls ExecuteCore
198+
CL->>CL: Rejects request (C3)
199+
CL->>P: Throws <br/>RateLimiterRejectedException
200+
P->>C3: Propagate exception
201+
202+
D->>-CL: Returns result (C1)
203+
CL->>P: Returns result (C1)
204+
CL->>+D: Invokes (C2)
205+
P->>C1: Returns result
206+
D->>-CL: Returns result (C2)
207+
CL->>P: Returns result (C2)
208+
P->>C2: Returns result
209+
```
210+
77211
## Disposal of rate limiters
78212

79213
The `RateLimiter` is a disposable resource. When you explicitly create a `RateLimiter` instance, it's good practice to dispose of it once it's no longer needed. This is usually not an issue when manually creating resilience pipelines using the `ResiliencePipelineBuilder`. However, when dynamic reloads are enabled, failing to dispose of discarded rate limiters can lead to excessive resource consumption. Fortunately, Polly provides a way to dispose of discarded rate limiters, as demonstrated in the example below:

docs/strategies/retry.md

+54
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,60 @@ new ResiliencePipelineBuilder().AddRetry(new RetryStrategyOptions
104104
| `OnRetry` | `null` | Action executed when retry occurs. |
105105
| `MaxDelay` | `null` | Caps the calculated retry delay to a specified maximum duration. |
106106

107+
## Diagrams
108+
109+
Let's suppose we have a retry strategy with `MaxRetryAttempts`: `2`.
110+
111+
### Happy path sequence diagram
112+
113+
```mermaid
114+
%%{init: {'theme':'dark'}}%%
115+
sequenceDiagram
116+
actor C as Caller
117+
participant P as Pipeline
118+
participant R as Retry
119+
participant D as DecoratedUserCallback
120+
121+
C->>P: Calls ExecuteAsync
122+
P->>R: Calls ExecuteCore
123+
Note over R,D: Initial attempt
124+
R->>+D: Invokes
125+
D->>-R: Fails
126+
R->>R: Sleeps
127+
Note over R,D: 1st retry attempt
128+
R->>+D: Invokes
129+
D->>-R: Returns result
130+
R->>P: Returns result
131+
P->>C: Returns result
132+
```
133+
134+
### Unhappy path sequence diagram
135+
136+
```mermaid
137+
%%{init: {'theme':'dark'}}%%
138+
sequenceDiagram
139+
actor C as Caller
140+
participant P as Pipeline
141+
participant R as Retry
142+
participant D as DecoratedUserCallback
143+
144+
C->>P: Calls ExecuteAsync
145+
P->>R: Calls ExecuteCore
146+
Note over R,D: Initial attempt
147+
R->>+D: Invokes
148+
D->>-R: Fails
149+
R->>R: Sleeps
150+
Note over R,D: 1st retry attempt
151+
R->>+D: Invokes
152+
D->>-R: Fails
153+
R->>R: Sleeps
154+
Note over R,D: 2nd retry attempt
155+
R->>+D: Invokes
156+
D->>-R: Fails
157+
R->>P: Propagates failure
158+
P->>C: Propagates failure
159+
```
160+
107161
## Patterns
108162

109163
### Limiting the maximum delay

docs/strategies/timeout.md

+10-10
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,13 @@ sequenceDiagram
8888
actor C as Caller
8989
participant P as Pipeline
9090
participant T as Timeout
91-
participant DM as DecoratedMethod
91+
participant D as DecoratedUserCallback
9292
9393
C->>P: Calls ExecuteAsync
9494
P->>T: Calls ExecuteCore
95-
T->>+DM: Invokes
96-
DM->>DM: Performs <br/>long-running <br/>operation
97-
DM->>-T: Returns result
95+
T->>+D: Invokes
96+
D->>D: Performs <br/>long-running <br/>operation
97+
D->>-T: Returns result
9898
T->>P: Returns result
9999
P->>C: Returns result
100100
```
@@ -107,18 +107,18 @@ sequenceDiagram
107107
actor C as Caller
108108
participant P as Pipeline
109109
participant T as Timeout
110-
participant DM as DecoratedMethod
110+
participant D as DecoratedUserCallback
111111
112112
C->>P: Calls ExecuteAsync
113113
P->>T: Calls ExecuteCore
114-
T->>+DM: Invokes
114+
T->>+D: Invokes
115115
activate T
116-
activate DM
117-
DM->>DM: Performs <br/>long-running <br/>operation
116+
activate D
117+
D->>D: Performs <br/>long-running <br/>operation
118118
T->T: Times out
119119
deactivate T
120-
T->>DM: Propagates cancellation
121-
deactivate DM
120+
T->>D: Propagates cancellation
121+
deactivate D
122122
T->>P: Throws <br/>TimeoutRejectedException
123123
P->>C: Propagates exception
124124
```

0 commit comments

Comments
 (0)