Как настроить несколько политик повторных попыток в MassTransit - PullRequest
1 голос
/ 14 марта 2019

Мне нужны две отдельные политики повторных попыток для конкретного потребителя. Один для HttpRequestException и SocketException, а другой для пользовательского DatabaseException и необработанного SqlException. Я хочу сделать это, потому что я хочу иметь отдельные экспоненциальные интервалы повторения для обоих.

У меня есть следующая конфигурация:

cfg.ReceiveEndpoint(
    host,
    "ExampleQueueName",
    ec =>
    {
        ec.Consumer<ExampleConsumer>(context);
        ec.EnablePriority(5);
        ec.UseRetry(retryConfig =>
        {
            // exponential backup in minutes
            retryConfig.Intervals(new[] { 1, 2, 4, 8, 16, 32 }.Select(t => TimeSpan.FromSeconds(t)).ToArray());
            retryConfig.Handle<HttpRequestException>(x => x.IsTransient());
            retryConfig.Handle<SocketException>(x => x.IsTransient());
        });
        ec.UseRetry(retryConfig =>
        {
            // exponential backup in seconds
            retryConfig.Intervals(new[] { 1, 2, 4, 8, 16, 32 }.Select(t => TimeSpan.FromSeconds(t)).ToArray());
            retryConfig.Handle<DatabaseException>(x => x.IsTransient());
            retryConfig.Handle<SqlException>(x => x.IsTransient());
        });
    });

В настоящее время используется только второй. Первый кажется перезаписанным.

Я также пытался настроить повторные попытки второго уровня следующим образом:

cfg.ReceiveEndpoint(
    host,
    "QueueName",
    ec =>
    {
        ec.Consumer<ExampleConsumer>(context, factory =>
        {
            factory.UseRetry(retryConfig =>
            {
                // exponential backup in seconds for sql and concurrency exceptions
                retryConfig.Intervals(new[] { 1, 2, 4, 8, 16, 32 }.Select(t => TimeSpan.FromSeconds(t)).ToArray());
                retryConfig.Handle<DatabaseException>(x => x.IsTransient());
                retryConfig.Handle<SqlException>(x => x.IsTransient());
            });
        });
        ec.EnablePriority(5);
        ec.UseRetry(retryConfig =>
        {
            // exponential backup in minutes for http request exceptions
            retryConfig.Intervals(new[] { 1, 2, 4, 8, 16, 32 }.Select(t => TimeSpan.FromSeconds(t)).ToArray());
            retryConfig.Handle<DatabaseException>(x => x.IsTransient());
            retryConfig.Handle<SqlException>(x => x.IsTransient());
        });
    });

Но, похоже, это тоже не работает. Кто-нибудь знает, как я могу применить разные интервалы повторения для разных типов исключений?

1 Ответ

0 голосов
/ 14 марта 2019

MassTransit строит все как конвейер, и порядок фильтров имеет значение. Переписав приведенный выше пример, следует решить проблему (все, что я сделал, это переместил Потребителя до конца).

cfg.ReceiveEndpoint(
host,
"ExampleQueueName",
ec =>
{
    ec.EnablePriority(5);
    ec.UseRetry(retryConfig =>
    {
        retryConfig.Intervals(new[] { 1, 2, 4, 8, 16, 32 }.Select(t => TimeSpan.FromSeconds(t)).ToArray());
        retryConfig.Handle<HttpRequestException>(x => x.IsTransient());
        retryConfig.Handle<SocketException>(x => x.IsTransient());
    });
    ec.UseRetry(retryConfig =>
    {
        retryConfig.Intervals(new[] { 1, 2, 4, 8, 16, 32 }.Select(t => TimeSpan.FromSeconds(t)).ToArray());
        retryConfig.Handle<DatabaseException>(x => x.IsTransient());
        retryConfig.Handle<SqlException>(x => x.IsTransient());
    });
    ec.Consumer<ExampleConsumer>(context);
});
...