Политика Polly для регистрации исключения и повторного выброса

Я планирую использовать Polly для создания политики для регистрации исключение и повторный выброс. Я не нашел существующего метода, который позволял бы это делать из коробки, но некоторые варианты, которые я вижу,

Резерв

// Specify a substitute value or func, calling an action (e.g. for logging)
// if the fallback is invoked.
Policy.Handle<Whatever>()
.Fallback<UserAvatar>(UserAvatar.Blank,
    onFallback: (exception, context) =>
    {
        _logger.Log(exception, context);
        throw exception;
    });

Вопрос: можно ли генерировать исключение из Fallback?

Тайм-аут

Policy.Timeout(1, T30meoutStrategy.Pessimistic,
(context, timespan, task) =>
{
    // ContinueWith important!: the abandoned task may very well still be executing,
    // when the caller times out on waiting for it!
    task.ContinueWith(t =>
    {
        if (t.IsFaulted)
        {
            logger.Error(context,t.Exception);
            throw exception;
        }
    });
}

Или Повторить

Policy.Handle<DivideByZeroException>().Retry(0,
(exception, retryCount) =>
{
    logger.Error(context,exception);
    throw exception;
});

Вопрос: поддерживается ли 0 попыток?

Или KISS и напиши просто попробуй / поймай с броском самостоятельно.

Какой из этих методов лучше? Что вы порекомендуете?


person Michael Freidgeim    schedule 22.03.2017    source источник


Ответы (2)


Если у вас еще нет Polly, попробуйте / поймать будет проще.

Если у вас уже есть Polly, FallbackPolicy можно безопасно переназначить так, как вы предлагаете. onFallback делегат и резервное действие или значение не регулируются .Handle<>() пунктами Политики, поэтому вы можете безопасно повторно генерировать исключение из onFallback делегата.

Policy<UserAvatar>.Handle<Whatever>()
.Fallback<UserAvatar>(UserAvatar.Blank,
    onFallback: (exception, context) =>
    {
        _logger.Log(exception, context);
        throw exception;
    });

Подход, описанный в вашем вопросе с помощью TimeoutPolicy, будет фиксировать только исключения, созданные делегатами вызывающего абонента. ранее ушел из-за тайм-аута, и только в TimeoutMode.Pessimistic; не все исключения.


Подход, описанный в вашем вопросе с помощью .Retry(0, ...), не сработает. Если повторные попытки не указаны, делегат onRetry не будет вызываться.


Чтобы избежать беспорядка перепрофилирования FallbackPolicy, вы также можете написать свой собственный LogThenRethrowPolicy в структурах Полли. Этот коммит (который добавил простой _ 12_) иллюстрирует минимум, необходимый для добавления новой политики. Вы можете добавить реализацию, аналогичную NoOpPolicy, но только try { } catch { /* log; rethrow */ }


ИЗМЕНИТЬ Январь 2019: Polly.Contrib теперь также содержит Polly. Contrib.LoggingPolicy, который может в этом помочь.

person mountain traveller    schedule 25.03.2017
comment
Вы знаете, где находится пакет NuGet для LoggingPolicy? Я не вижу ссылки на GitHub, и я попытался найти в NuGet Polly.Contrib и Polly.Contrib.LoggingPolicy. Кажется, что ни один из пакетов не существует, хотя я нашел несколько подпакетов для Polly.Contrib, которые, похоже, не связаны. - person carlin.scott; 07.07.2020

https://github.com/App-vNext/Polly-Samples/blob/master/PollyDemos/Async/AsyncDemo02_WaitAndRetryNTimes.cs показывает, что вы можете использовать параметр onRetry:, по крайней мере, для WaitAndRetryAsync. Я еще не смотрел на остальных.

HttpPolicyExtensions
.HandleTransientHttpError()
.WaitAndRetryAsync(3,
    retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))  // exponential back-off: 2, 4, 8 etc
                    + TimeSpan.FromMilliseconds(Jitterer.Next(0, 1000)), // plus some jitter: up to 1 second
    onRetry: (response, calculatedWaitDuration) =>
    {
        logger.LogError($"Failed attempt. Waited for {calculatedWaitDuration}. Retrying. {response.Exception.Message} - {response.Exception.StackTrace}");
    }
);
person AlignedDev    schedule 02.11.2018
comment
Я не хотел повторять попытку, просто зарегистрируйтесь и повторите попытку. - person Michael Freidgeim; 02.11.2018