Polly Circuit Breaker - exceptions gérées et non gérées
Je souhaite utiliser Polly pour implémenter un modèle de disjoncteur.
Dans la documentation, il y a une description de l'état Half Open , et il est dit:
- Si une exception gérée est reçue, cette exception est renvoyée, et le circuit passe immédiatement à nouveau pour s'ouvrir et reste à nouveau ouvert pendant la période configurée.
- Si une exception non gérée est reçue, le circuit reste à moitié ouvert.
Je ne suis pas sûr de comprendre la différence entre les exceptions gérées et non gérées. Nous décrivons un cas où une action est exécutée par la stratégie et lève une exception.
Quand ils disent que l'exception est gérée, où veulent-ils dire qu'elle est gérée? parce que comme nous l'avons dit, l'action l'a jeté, alors cela ne signifie-t-il pas qu'il n'est pas géré?
Cela ne me fait pas comprendre complètement quand l'état à moitié ouvert reste à moitié ouvert et quand passe-t-il à ouvrir.
Réponses
Lorsque vous définissez une stratégie de disjoncteur, vous pouvez définir le type d'exception (s) à prendre en compte par l' implémentation CB . En d'autres termes, vous pouvez répertorier les exceptions qui doivent être traitées comme des échecs d'exécution et qui doivent être comptées dans le décompte des échecs successifs.
Vous pouvez définir la liste des exceptions avec la combinaison d' appels de méthode Handle<T>
et Or<T>
.
Examinons ce concept à l'aide d'un exemple simple:
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}"));
- La politique de disjoncteur considère tous les
ArgumentException
s (y comprisArgumentNullException
etArgumentOutOfRangeException
) comme une exception gérée.- Cela signifie que si le délégué appelé lève l'une de ces trois exceptions, il augmentera le nombre d'échecs successifs et si le seuil est atteint, il se cassera.
- La politique de nouvelle tentative est déclenchée en cas
ArgumentException
et en cas deNotSupportedException
également.- Si l'un de ces éléments est levé, il dormira pendant une seconde, puis il essaiera de réexécuter le même délégué.
Donc, du point de vue du disjoncteur, si un NotSupportedException
est lancé, il ne sera pas considéré >> d'où le nom non géré.
Voici comment notre exemple de méthode est implémenté qui lancera un ArgumentException
ou un 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");
}
L'utilisation des politiques:
var strategy = Policy.Wrap(retry, circuitBreaker);
try
{
strategy.Execute(SampleCall);
Console.WriteLine("Succeeded");
}
catch (NotSupportedException)
{
Console.WriteLine("Failed");
}
Sortie lorsque threshold
est réglé sur 3
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
Une fois que le CB a été transféré dans l' HalfOpen
état, alors le SampleCall
jette seulement NotSupportedException
s. Ce n'est pas géré par le CB c'est pourquoi il reste dans l' HalfOpen
état.
Sortie lorsque threshold
est réglé sur 2
Retry 01.000 : ArgumentException
Retry 01.000 : NotSupportedException
Retry 01.000 : NotSupportedException
Retry 01.000 : NotSupportedException
Retry 01.000 : NotSupportedException
Failed
Le CB ne s'est pas cassé car il n'y a pas eu deux successifs ArgumentException
. Mais la nouvelle tentative s'est déclenchée car elle gère également NotSupportedException
.
Sortie lorsque threshold
est réglé sur 4
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
Parce SampleCall
qu'il a jeté ArgumentException
quand le CB était dans l' HalfOpen
état, c'est pourquoi CB a considéré cela comme une exception gérée et s'est transféré de HalfOpen
à Open
.