2

I have azure function which trigger when we ave new message into service bus topic.

In azure function I checked the customer api is available or not by calling it and checking its status code.

If status code is 200 I need to process the message else put this message into dead-letter and after some interval when customer api is available then process all dead letter message also.

 public static class Function1
    {
        [FunctionName("Function1")]
        public static void Run([ServiceBusTrigger("customer-order", "customer-order", Connection = "")]string mySbMsg, ILogger log)
        {
            // 1.call customer api to check it is available or not 
            // 2.if it is up and running then process the message else put message into dead-letter 
            // and after some interval when customer ai is available process dead-letter messages

            log.LogInformation($"C# ServiceBus topic trigger function processed message: {mySbMsg}");
        }
    }

I can able to invoke customer api using HTTPClient and process message also.

but how to put message into dead-letter and How to execute dead-letter after some interval when customer api is available ?

Proposed Flow Will be

in azure function app which will trigger if new message is there into.

topic start step - Check api is available or down if api is available

process the current message if api is down then do not process

message here we have two choices

1a.put current message into dead letter  

1b.put current message back into main but if we do this then again function app will trigger as its new message trigger based and start step will continue.
Neo
  • 15,491
  • 59
  • 215
  • 405
  • 1
    Normally you need to delete the message from queue once you successfully process the message. If the message is not deleted it will reappear for processing. You can configure the queue for now many times the messages should be tried for processing before they end up in case letter queue. And in the function you should not delete the message if the API is not available. – Chetan Aug 14 '19 at 09:58
  • so you mean to say instead of using dead letter we should keep the message into main topic ? but how those messages got process later when api is available it will process automatically? because function will only trigger when new message is there? – Neo Aug 14 '19 at 10:02
  • how to process dead letter messages? – Neo Aug 14 '19 at 10:04
  • 2
    You need to write another function for that. – Chetan Aug 14 '19 at 10:08
  • but how do we insure there in another function will run only when api is available ? – Neo Aug 14 '19 at 10:10
  • 1
    You have a different problem to solve here. Let me give you proper solution approach in some time – Chetan Aug 14 '19 at 10:16
  • 1
    I agree with @ChetanRanpariya. You will need a new function to process the dead-letter queue messages. This could be a timer triggered function which will spin up at an interval, check the customer API is running and if it is, process the message. Or to stop code duplication - put the message back on the service bus queue to be processed by the original function. – Chris Aug 14 '19 at 10:33
  • but there is no point to put the message back on the service bus immediately as service is not available pls clarify if my understanding is wrong thanks – Neo Aug 14 '19 at 11:07
  • 1
    @Neo you wouldn't do it immediately. A timer triggered function would run sometime after the original function execution and check if the API is available. If it's not online then don't do anything. If it is online then put the message on the original queue and it will get processed as you know the API is available. Worst case, it goes back to dead-letter to try again later - but how often is this API going to be unavailable? – Chris Aug 14 '19 at 13:52
  • very rarely api will be unavailable – Neo Aug 14 '19 at 14:34
  • i have updated question with the flow please comment. – Neo Aug 14 '19 at 14:51

1 Answers1

2

Rather than putting this in dead letter queue, a better approach would be to defer the message for a certain duration.

If a message cannot be processed because a particular resource for handling that message is temporarily unavailable but message processing should not be summarily suspended, a way to put that message on the side for a few minutes is to remember the SequenceNumber in a scheduled message to be posted in a few minutes, and re-retrieve the deferred message when the scheduled message arrives.

See this answer for an example to how to do deferral in Azure functions v2. Note that the input binding is using message of type Message and is also using the injected MessageReceiver. Those are needed to be able to call DeferAsync. The template code for service bus trigger sets the message type to string, so you would have to change signature as described in that answer.

About deferred messages:

Deferred messages remain in the main queue along with all other active messages (unlike dead-letter messages that live in a subqueue), but they can no longer be received using the regular Receive/ReceiveAsync functions. To retrieve a deferred message, its owner is responsible for remembering the SequenceNumber as it defers it. Any receiver that knows the sequence number of a deferred message can later receive the message explicitly with Receive(sequenceNumber).

How to schedule messages with sequence number of deferred messages so that deferred message can be processed at a later time:

You can schedule messages either by setting the ScheduledEnqueueTimeUtc property when sending a message through the regular send path, or explicitly with the ScheduleMessageAsync API

Turbo
  • 2,179
  • 18
  • 38
  • instead of separate function can it be same function? – Neo Aug 14 '19 at 11:08
  • Yes. In your example, in the run method, once you detect that a dependent service is down, you can choose to call `DeferAsync`, and also push a [scheduled message](https://learn.microsoft.com/en-us/azure/service-bus-messaging/message-sequencing#scheduled-messages) to the queue. The *defer* call will cause the message to remain in the queue but will not be pushed to the listener. When the scheduled message is received by the listener, it can then retrieve the deferred message at that point. The first link in my anwer above describes this pattern. – Turbo Aug 14 '19 at 19:21