-
Notifications
You must be signed in to change notification settings - Fork 1
/
PolicyWrapDemo.cs
104 lines (95 loc) · 3.44 KB
/
PolicyWrapDemo.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Polly;
using System.Text.Json;
namespace PollyDemo
{
class PolicyWrapDemo
{
public class Entry
{
public Guid Id { get; set; }
public string Subject { get; set; }
}
static IEnumerable<Entry> Call3rdApi(string srcName, int delayTime)
{
Task.Delay(delayTime * 1000).Wait();
return Enumerable.Range(1, 2).Select(o =>
new Entry
{
Id = Guid.NewGuid(),
Subject = $"Data from ExtraData[{srcName}] {DateTime.Now.Ticks % 100000:00000}"
});
}
static Dictionary<string, Func<IEnumerable<Entry>>> extDataJobs =
new Dictionary<string, Func<IEnumerable<Entry>>>
{
["SrcA"] = () => Call3rdApi("A", 3),
["SrcB"] = () => Call3rdApi("B", 8),
["SrcC"] = () => { throw new ApplicationException("Error"); }
};
public static void Test()
{
PreparePolicy();
var data = QueryData();
var options = new JsonSerializerOptions
{
WriteIndented = true
};
Console.WriteLine(JsonSerializer.Serialize(data, options));
}
static Polly.Wrap.PolicyWrap<IEnumerable<Entry>> policy = null;
static void PreparePolicy()
{
var timeoutPolicy =
Policy.Timeout(TimeSpan.FromSeconds(5), Polly.Timeout.TimeoutStrategy.Pessimistic);
var timeoutFallbackPolicy = Policy<IEnumerable<Entry>>
.Handle<Polly.Timeout.TimeoutRejectedException>()
.Fallback((context) =>
new List<Entry>() {
new Entry
{
Id = Guid.NewGuid(),
Subject = $"Warning: [{context["Src"]}] API timeout"
}
}, onFallback: (ex, ctx) => { });
var fallbackPolicy = Policy<IEnumerable<Entry>>.Handle<Exception>()
.Fallback((context) =>
new List<Entry>() {
new Entry
{
Id = Guid.NewGuid(),
Subject = $"Warning: [{context["Src"]}] API failed"
}
}, onFallback: (ex, ctx) => { });
policy = fallbackPolicy.Wrap(timeoutFallbackPolicy).Wrap(timeoutPolicy);
}
static IEnumerable<Entry> QueryData()
{
var list = new List<Entry>();
//database query simulation
list.Add(new Entry
{
Id = Guid.NewGuid(),
Subject = "Data from local service"
});
Parallel.ForEach(extDataJobs.Keys, (src) =>
{
var extData = policy.Execute((context) =>
{
return extDataJobs[src]();
}, contextData: new Dictionary<string, object>
{
["Src"] = src
});
lock (list)
{
list.AddRange(extData);
}
});
return list;
}
}
}