如何在RegisterHandler中修改ServiceStack RabbitMQ消息,第2部分

时间:2014-12-18 22:13:26

标签: servicestack rabbitmq

作为我的original question的后续,当我从我的Web服务抛出异常时,它们被ServiceStack转换为更多HTTP友好的响应代码,这对于感兴趣的一方来说是个问题,一个Windows服务(MQ逻辑服务器) )它只收到500内部服务器错误。

有没有办法在内部异常属性中保留OutBoundAgentNotFoundException,以便我可以在其他地方检查它并从中执行操作?

Web服务端点:

//This is a callback that the phone system uses to notify us of what routing decision was made.
//It's now up to this method to assign it to the agent, or send it back to the queue via exceptions
public object Get(OutBoundILeadRequest request)
{
    if (request == null) throw new ArgumentNullException("request");

    _log.Debug("OutBoundILeadRequest: {0}".Fmt(request.ToJson()));

    // assign the agent to the lead

    // Agent phone extension is called, 1 and 2 are pressed, accepts call "Agent":"9339","Status":"0"
    // Agent phone extension is called, 1 and 2 are pressed, but no answer or wrong number "Agent":"9339","Status":"0"
    if (request.Status == "0" && !string.IsNullOrEmpty(request.Agent))
    {
        //assignment

    }


    // throw will send it back to the queue and then it will be re-tried, then it will be sent to the dlq  
    // https://stackoverflow.com/questions/27519209


    // Agent phone extension is called, but no response from Agent => "AgentsTalking":"0","Status":"3" 
    // this action puts them in NOT READY (Cisco Agent Desktop)            
    if (request.Status == "3" && !string.IsNullOrEmpty(request.AgentsTalking) && request.AgentsTalking == "0")
    {
        //retry

    }


    // No one assigned to this Phone Queue is in a ready state => "AgentsTalking":"number of agents on the phone","Status":"1" (Potentially can redistribute the phone)
    if (request.Status == "1" && !string.IsNullOrEmpty(request.AgentsTalking) && request.AgentsTalking != "0")
    {
        //retry
        throw new OutBoundAgentNotFoundException("<NEW MEWSSAGE HERE 1>");
    }

    // No one assigned to this Phone Queue is in a ready state => "AgentsTalking":"0","Status":"1" (No one in the Call Center)
    if (request.Status == "1" && !string.IsNullOrEmpty(request.AgentsTalking) && request.AgentsTalking == "0")
    {
        //retry
        throw new OutBoundAgentNotFoundException("<NEW MEWSSAGE HERE 2>");
    }
    // 'should' not get here 
    throw new OutBoundAgentNotFoundException("<NEW MEWSSAGE HERE 3>");
}

在Windows服务中注册处理程序:

mqServer.RegisterHandler<OutboundILeadPhone>(m =>
{
    var db = container.Resolve<IFrontEndRepository>();
    db.SaveMessage(m as Message);
    return ServiceController.ExecuteMessage(m);
}, PhoneApi.OnExceptionLeadInformation , 1);

Windows服务异常处理程序:

public static void OnExceptionLeadInformation(IMessage<OutboundILeadPhone> request, Exception exception)
{

      // Here is where I'd like to inspect the type of exception and Nak/requeue the Message

}

Windows服务端点:

//This method is being called in response to a message being published by the 
//RabittMQ Broker (Queue mq:OutboundILeadPhone.inq)
//The result of sucessuflully processing this message will result in a message being published to 
// (Queue mq:OutboundILeadPhone.outq)
public object Post(OutboundILeadPhone request)
{
    if (request == null) throw new ArgumentNullException("request");

    //By default there is only 1 worker thread (per message type) 
    //that's used to process the request, so you can just add a 
    //Thread.Sleep() in your Service to delay processing of the request 
    //as the next request only gets processed after the previous one has finished. 

    int delay = 2000;
    Thread.Sleep(delay); //todo:smp configurable

    var profiler = Profiler.Current;
    using (profiler.Step("PhoneApi DirectApiServices POST OutboundILeadPhone"))
    {
        try
        {





        }
        catch (Exception exception)
        {
            _log.Error(request.ToJson(), exception);
            throw;
        }

    }
    /*_log.Debug(profiler.GetTimingHierarchy());*/

    return null;
}

谢谢你, 斯蒂芬

1 个答案:

答案 0 :(得分:1)

我只是committed a change将原始异常存储在InnerException中,MQ错误处理程序现在通过MessageHandler处理消息,因此您的错误回调现在可以访问原始MqClient实例检索消息,该消息可用于消息消息,例如:

public CustomException LastCustomException;

public void HandleMqCustomException(IMessageHandler mqHandler, 
    IMessage<MqCustomException> message, Exception ex)
{
    LastCustomException = ex.InnerException as CustomException;

    bool requeue = !(ex is UnRetryableMessagingException)
        && message.RetryAttempts < 1;

    if (requeue)
    {
        message.RetryAttempts++;
    }

    message.Error = ex.ToResponseStatus();
    mqHandler.MqClient.Nak(message, requeue: requeue, exception: ex);
}

这是来自MqAppHostTests,它显示了如何从服务中检索原始异常,并从原始MQ客户端实例中获取消息。

此更改可从 v4.0.35 + 获得,现在为available on MyGet