2016-07-05 4 views
2

Использование NServiceBus 4.3 Я хочу отправить сообщение в очередь ошибок при возникновении определенных условий.Отправить сообщение для error queue first time

Сценарий заключается в том, что когда я получаю сообщение, я проверяю, ссылается ли это сообщение на 1 или более элементов нашей базы данных. Если есть несколько ссылок, я бросаю AmbiguousItemException и поймаю его. Мне нужно отправить электронное письмо ответственному лицу за предоставление мне правильной информации. Все это выяснено, но я не хочу, чтобы это сообщение было снова проверено. Вместо этого я предпочел бы переместить его в очередь ошибок, поэтому, когда мы вернем необходимую информацию, мы можем добавить свойство nullable и вернуть сообщение в очередь для обработки. Я пробовал использовать _bus.ForwardCurrentMessageTo("error"), _bus.Send("error", message), _bus.SendLocal(message). Последнее в основном помещает сообщение в бесконечный цикл. Код вроде как.

public class MoveToErrorQueue 
{ 
    private readonly IBus _bus; 

    public MoveToErrorQueue(IBus bus) 
    { 
     _bus = bus; 
    } 

    public virtual void Send(ResubmitMessage message) 
    { 
     message.Foo= -1; 
     _bus.Send("error", message); 
    } 
} 

и код, который называет его

 try 
     { 
      //removed for brevity 
     } 
     catch (AmbiguousItemException ex) 
     { 
      Log.Error(ex); 
      sendNotificationCommand.FailureMessage = ex.Message; 
      _moveToErrorQueue.Send(commandMesage); 
     } 
     SendNotification(sendScanningNotificationCommand); 

ответ

6

Из того, что вы описываете, это звучит, как у вас есть длинный работает бизнес-процесс. Это кандидат для using a Saga. Sagas обрабатывает входящие сообщения, как обработчик, но сага также позволяет отслеживать состояние. Поэтому вместо того, чтобы пытаться отбросить ваше сообщение в очередь ошибок (это не очень хорошая идея), вы можете вместо этого установить флаг какого-либо типа, например boolean или enum в Saga, который укажет, что вы получили сообщение, ссылаясь на 1 или более элементов в вашей базе данных ", как вы выразились.

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

Как только вы получите необходимую информацию, вы можете предпринять любые действия, а затем отправить сообщение обратно в Сагу, в котором говорится, чтобы продолжить процесс и/или пометить его как завершенное и закрыть.

You can learn more about Sagas here

+0

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

+1

Команда уведомления может вернуться к Саге, и она может справиться с ней самой. Это было просто предложение. Вы можете так же легко поместить запись в таблицу или отправить электронное письмо себе и т. Д. Разрушение очереди ошибок не рекомендуется. Это не то, для чего оно предназначалось. Я бы не рекомендовал этого. –

+2

Просто примечание, я думаю, @ColinPear означает, что очередь ошибок не должна быть уловкой всех для ошибок проверки бизнеса. –

1

можно подключить к Сходы API и возвращает «нет попыток» номер, по существу послать определенные исключения из очереди ошибок

http://docs.particular.net/nservicebus/errors/automatic-retries#second-level-retries-custom-retry-policy-exception-based-policy

var retriesSettings = busConfiguration.SecondLevelRetries(); 
retriesSettings.CustomRetryPolicy(MyCustomRetryPolicy); 

Политика

TimeSpan MyCustomRetryPolicy(TransportMessage transportMessage) 
{ 
    if (transportMessage.ExceptionType() == typeof(MyBusinessException).FullName) 
    { 
     // Do not retry for MyBusinessException 
     return TimeSpan.MinValue; 
    } 

    if (transportMessage.NumberOfRetries() >= 3) 
    { 
     return TimeSpan.MinValue; 
    } 

    return TimeSpan.FromSeconds(5); 
} 

A й помощник заголовка

static class ErrorsHeadersHelper 
{ 
    internal static int NumberOfRetries(this TransportMessage transportMessage) 
    { 
     string value; 
     if (transportMessage.Headers.TryGetValue(Headers.Retries, out value)) 
     { 
      return int.Parse(value); 
     } 
     return 0; 
    } 

    internal static string ExceptionType(this TransportMessage transportMessage) 
    { 
     return transportMessage.Headers["NServiceBus.ExceptionInfo.ExceptionType"]; 
    } 
} 
+0

Это должно сработать, но, возможно, следует отметить, что FLR все равно будет работать через сконфигурированное количество раз, прежде чем передать его в SLR.Я не знаю, можете ли вы подключиться к конвейеру, пока FLR делает это. Насколько я понимаю, вы не добавляете заголовки до тех пор, пока FLR не исчерпает свои попытки. –

+0

@ JustinSelf правильный. есть ли у вас требование контролировать FLR на основе типа исключения? если бы я мог изучить его и добавить образец, если это возможно – Simon

Смежные вопросы