-
Notifications
You must be signed in to change notification settings - Fork 49
Expand file tree
/
Copy pathRepeatedFailuresOverTimeCircuitBreaker.cs
More file actions
76 lines (62 loc) · 2.48 KB
/
RepeatedFailuresOverTimeCircuitBreaker.cs
File metadata and controls
76 lines (62 loc) · 2.48 KB
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
namespace NServiceBus
{
using System;
using System.Threading;
using System.Threading.Tasks;
using Logging;
class RepeatedFailuresOverTimeCircuitBreaker : IDisposable
{
public RepeatedFailuresOverTimeCircuitBreaker(string name, TimeSpan timeToWaitBeforeTriggering, Action<Exception> triggerAction, TimeSpan delayAfterFailure)
{
this.delayAfterFailure = delayAfterFailure;
this.name = name;
this.triggerAction = triggerAction;
this.timeToWaitBeforeTriggering = timeToWaitBeforeTriggering;
Logger.DebugFormat("RepeatedFailuresOverTime circuit breaker {0} that will trigger after {1} ", name, timeToWaitBeforeTriggering, delayAfterFailure);
timer = new Timer(CircuitBreakerTriggered);
}
public void Dispose()
{
timer.Dispose();
GC.SuppressFinalize(this);
}
public void Success()
{
var oldValue = Interlocked.Exchange(ref failureCount, 0);
if (oldValue == 0)
{
return;
}
timer.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
Logger.InfoFormat("The circuit breaker for {0} is now disarmed", name);
}
public Task Failure(Exception exception)
{
lastException = exception;
var newValue = Interlocked.Increment(ref failureCount);
if (newValue == 1)
{
timer.Change(timeToWaitBeforeTriggering, NoPeriodicTriggering);
Logger.WarnFormat("The circuit breaker for {0} is now in the armed state", name);
}
return Task.Delay(delayAfterFailure);
}
void CircuitBreakerTriggered(object state)
{
if (Interlocked.Read(ref failureCount) > 0)
{
Logger.WarnFormat("The circuit breaker for {0} will now be triggered", name);
triggerAction(lastException);
}
}
readonly TimeSpan delayAfterFailure;
long failureCount;
Exception lastException;
readonly string name;
readonly Timer timer;
readonly TimeSpan timeToWaitBeforeTriggering;
readonly Action<Exception> triggerAction;
static readonly TimeSpan NoPeriodicTriggering = TimeSpan.FromMilliseconds(-1);
static readonly ILog Logger = LogManager.GetLogger<RepeatedFailuresOverTimeCircuitBreaker>();
}
}