8

I don't understand why the following handler (processMessageAsync) referenced below is not being triggered for a specific topic name but succeeds for other topic names:

subscriptionClient.RegisterMessageHandler(processMessageAsync, msgOptions)

The following is my Subscriber class:

open System
open System.Linq
open System.Threading
open System.Text
open System.Threading.Tasks
open Microsoft.Azure.ServiceBus

type Subscriber(connectionString:string, topic:string, subscription:string) =

    let mutable subscriptionClient : SubscriptionClient = null

    let exceptionReceivedHandler (args:ExceptionReceivedEventArgs) =
        printfn "Got an exception: %A" args.Exception
        Task.CompletedTask

    let processMessageAsync (message:Message) (_:CancellationToken) = 

        try

            let _ = Encoding.UTF8.GetString(message.Body)
            subscriptionClient.CompleteAsync(message.SystemProperties.LockToken) |> Async.AwaitTask |> Async.RunSynchronously

            Task.CompletedTask

        with
            _ -> Task.CompletedTask

    member x.Listen() =

        async {

            subscriptionClient <- new SubscriptionClient(connectionString, topic, subscription)
            subscriptionClient.OperationTimeout <- TimeSpan.FromMinutes(3.0)

            let! rulesFound     = subscriptionClient.GetRulesAsync() |> Async.AwaitTask
            let  hasDefaultRule = rulesFound.Any(fun r -> r.Name = RuleDescription.DefaultRuleName)

            if hasDefaultRule then
                do! subscriptionClient.RemoveRuleAsync(RuleDescription.DefaultRuleName) |> Async.AwaitTask

            let msgOptions = MessageHandlerOptions(fun args -> exceptionReceivedHandler(args))
            msgOptions.AutoComplete         <- false
            msgOptions.MaxAutoRenewDuration <- TimeSpan.FromMinutes(1.0)
            msgOptions.MaxConcurrentCalls   <- 1

            subscriptionClient.RegisterMessageHandler(processMessageAsync, msgOptions)
        }

    member x.CloseAsync() =

        async {

            do! subscriptionClient.CloseAsync() |> Async.AwaitTask
        }

Here's how I attempt to run the subscriber:

open System
open Subscription.Console

let connectionString = <connection_string>

[<EntryPoint>]
let main argv =

    printfn "Welcome to Subscription.Console"

    let topic,subscription = "Topic.courier-accepted","Subscription.all-messages"
    let subscriber = Subscriber(connectionString, topic, subscription)

    async { do! subscriber.Listen()
          } |> Async.RunSynchronously

    Console.ReadKey() |> ignore

    async { do! subscriber.CloseAsync()
          } |> Async.RunSynchronously

    0 // return an integer exit code 

The following code publishes a message that my subscriber should receive (but doesn't):

[<Fact>]
let ``Publish courier-accepted to servicebus``() =

    async {

        // Setup
        let  client    = TopicClient(sbConnectionstring, "Topic.courier-accepted")
        let! requestId = requestId()

        let updated = requestId |> modifyRequestId someCourierResponse
        let json    = JsonConvert.SerializeObject(updated)
        let message = Message(Encoding.UTF8.GetBytes(json))

        message.Label <- sprintf "request-id(%s)" (requestId.ToString())

        // Test
        do! client.SendAsync(message) |> Async.AwaitTask

        // Teardown
        do! client.CloseAsync()       |> Async.AwaitTask
    }

NOTE:

What's interesting about the code above, is that when I have an Azure Function running with a ServiceBusTrigger set to the same topic and subscription name, that Azure Function is triggered each time I run the test.

  • I don't receive any exception messages
  • exceptionReceivedHandler function is never triggered on my Subscriber instance
  • I don't observe any user errors on my Azure dashboard for the servicebus resource

Succeeds with different topic name

If I change the topic name to "courier-requested" then the subscriber instance receives messages:

[<Fact>]
let ``Publish courier-requested to servicebus topic``() =

    // Setup
    let client    = TopicClient(sbConnectionstring, "Topic.courier-requested")
    let message   = Message(Encoding.UTF8.GetBytes(JsonFor.courierRequest))
    message.Label <- sprintf "courier-id(%s)" "b965f552-31a4-4644-a9c6-d86dd45314c4"

    // Test
    async {

        do! client.SendAsync(message) |> Async.AwaitTask
        do! client.CloseAsync()       |> Async.AwaitTask
    }

Here's the subscription that has the topic name adjustment:

[<EntryPoint>]
let main argv =

    printfn "Welcome to Subscription.Console"

    let topic,subscription = "Topic.courier-requested","Subscription.all-messages"
    let subscriber = Subscriber(connectionString, topic, subscription)

    async { do! subscriber.Listen()
          } |> Async.RunSynchronously

    Console.ReadKey() |> ignore

    async { do! subscriber.CloseAsync()
          } |> Async.RunSynchronously

    0 // return an integer exit code

Here are the two topics in my Azure Portal: enter image description here

Clicking Topics in Portal has different Results:

I noticed that I have to click "courier-accepted" twice just to view it's subscriptions. However, I can click "courier-requested" once and immediately view its subscriptions.

Scott Nimrod
  • 11,206
  • 11
  • 54
  • 118
  • 1
    `I don't receive any exception messages`, maybe because you're swallowing the exceptions? I see a `with _` block after a `try` one – user1623521 Mar 23 '20 at 08:44
  • I did observe an exception after I created an additional subscription for the courier-accepted topic, launched the subscriber with a subscription value matching the one I just registered in the portal, and then deleting the recently created subscription while the subscriber is still running. – Scott Nimrod Mar 23 '20 at 09:11
  • I can't reproduce your issue on my side,it seems that you met the unnormal behaviour on the service bus portal. Maybe you could submit support ticket to the SB team. – Jay Gong Apr 08 '20 at 08:39
  • I submitted a ticket yesterday. – Scott Nimrod Apr 08 '20 at 13:58

1 Answers1

0

If I understand correctly that you tried deleting the problematic topic and recreating it, that sounds to me like a hiccup in Azure. You shouldn't get the behavior described above where one needs to be clicked twice. Sometimes I've created things in Azure, there's a problem somewhere downstream in their infrastructure, and a support request is the only way to get it resolved.