Polly Circuit Breaker behandelte und nicht behandelte Ausnahmen
Ich möchte Polly verwenden, um ein Leistungsschaltermuster zu implementieren.
In den Dokumenten gibt es eine Beschreibung des Half Open-Status und dort heißt es:
- Wenn eine behandelte Ausnahme empfangen wird, wird diese Ausnahme erneut ausgelöst, und die Schaltung wechselt sofort wieder zum Öffnen und bleibt für die konfigurierte Zeitspanne wieder geöffnet.
- Wenn eine nicht behandelte Ausnahme empfangen wird, bleibt der Stromkreis halb offen.
Ich bin mir nicht sicher, ob ich den Unterschied zwischen behandelten und nicht behandelten Ausnahmen verstehe. Wir beschreiben einen Fall, in dem eine Aktion von der Richtlinie ausgeführt wird und eine Ausnahme auslöst.
Wenn sie sagen, dass die Ausnahme behandelt wird, wo meinen sie dann, dass sie behandelt wird? denn wie gesagt, die Aktion hat es geworfen, heißt das nicht, dass es nicht behandelt wird?
Ich verstehe nicht ganz, wann der halb offene Zustand halb offen bleibt und wann er in den offenen Zustand übergeht.
Antworten
Wenn Sie eine Leistungsschalterrichtlinie definieren, können Sie festlegen, welche Art von Ausnahme (n) von der CB-Implementierung berücksichtigt werden sollen . Mit anderen Worten, Sie können die Ausnahmen auflisten, die als fehlgeschlagene Ausführung behandelt und in die Anzahl der aufeinanderfolgenden Fehler einbezogen werden sollen.
Sie können die Liste der Ausnahmen mit der Kombination von Handle<T>
und Or<T>
Methodenaufrufen definieren.
Lassen Sie uns dieses Konzept anhand eines einfachen Beispiels untersuchen:
var retry = Policy
.Handle<ArgumentException>()
.Or<NotSupportedException>()
.WaitAndRetry(5, _ => TimeSpan.FromSeconds(1),
onRetry: (exception, delay, context) => Console.WriteLine($"{"Retry",-10}{delay,-10:ss\\.fff}: {exception.GetType().Name}")); var circuitBreaker = Policy .Handle<ArgumentException>() .CircuitBreaker(2, TimeSpan.FromSeconds(1), onBreak: (ex, @break) => Console.WriteLine($"{"Break",-10}{@break,-10:ss\\.fff}: {ex.GetType().Name}"),
onReset: () => Console.WriteLine($"{"Reset",-10}"), onHalfOpen: () => Console.WriteLine($"{"HalfOpen",-10}"));
- Die Leistungsschalterrichtlinie betrachtet alle
ArgumentException
s (einschließlichArgumentNullException
undArgumentOutOfRangeException
) als behandelte Ausnahme.- Dies bedeutet, dass wenn der angerufene Delegat eine dieser drei Ausnahmen auslöst, die Anzahl der aufeinanderfolgenden Fehler erhöht wird und wenn der Schwellenwert erreicht wird, diese unterbrochen wird.
- Die Wiederholungsrichtlinie wird im Fall von
ArgumentException
und auch im Fall von ausgelöstNotSupportedException
.- Wenn einer dieser Punkte ausgelöst wird, wird er für eine Sekunde in den Ruhezustand versetzt und versucht dann, denselben Delegaten erneut auszuführen.
Wenn also aus der Sicht des Leistungsschalters a NotSupportedException
geworfen wird, wird es nicht berücksichtigt >>, daher der Name unbehandelt.
Auf diese Weise wird unsere Beispielmethode implementiert, die entweder ein ArgumentException
oder ein NotSupportedException
:
private static int count = 0;
private const int threshold = 3;
static void SampleCall()
{
count++;
if (count >= threshold) throw new NotSupportedException();
throw new ArgumentException("Nothing");
}
Die Verwendung der Richtlinien:
var strategy = Policy.Wrap(retry, circuitBreaker);
try
{
strategy.Execute(SampleCall);
Console.WriteLine("Succeeded");
}
catch (NotSupportedException)
{
Console.WriteLine("Failed");
}
Ausgabe wenn threshold
auf 3 gesetzt ist
Retry 01.000 : ArgumentException
Break 01.000 : ArgumentException
Retry 01.000 : ArgumentException
HalfOpen
Retry 01.000 : NotSupportedException
Retry 01.000 : NotSupportedException
Retry 01.000 : NotSupportedException
Failed
Nachdem sich die CB selbst in den HalfOpen
Zustand versetzt hat, werden SampleCall
nur NotSupportedException
s geworfen. Dies wird von der CB nicht erledigt, deshalb bleibt sie im HalfOpen
Staat.
Ausgabe wenn threshold
auf 2 gesetzt ist
Retry 01.000 : ArgumentException
Retry 01.000 : NotSupportedException
Retry 01.000 : NotSupportedException
Retry 01.000 : NotSupportedException
Retry 01.000 : NotSupportedException
Failed
Die CB brach nicht, weil es keine zwei aufeinanderfolgenden gab ArgumentException
. Der Wiederholungsversuch wurde jedoch ausgelöst, da er auch behandelt wird NotSupportedException
.
Ausgabe wenn threshold
auf 4 gesetzt ist
Retry 01.000 : ArgumentException
Break 01.000 : ArgumentException
Retry 01.000 : ArgumentException
HalfOpen
Break 01.000 : ArgumentException
Retry 01.000 : ArgumentException
HalfOpen
Retry 01.000 : NotSupportedException
Retry 01.000 : NotSupportedException
Failed
Da der SampleCall
Wurf geworfen hat, ArgumentException
als sich die CB in dem HalfOpen
Zustand befand, betrachtete CB dies als behandelte Ausnahme und übertrug sich von HalfOpen
auf Open
.