¿Por qué RegisterMessageHandler no funciona para un nombre de tema específico?

9

No entiendo por qué el siguiente controlador ( processMessageAsync ) al que se hace referencia a continuación no se activa para un nombre de tema específico, pero tiene éxito para otros nombres de tema:

subscriptionClient.RegisterMessageHandler(processMessageAsync, msgOptions)

La siguiente es mi clase de suscriptor :

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
        }

Así es como intento ejecutar el suscriptor :

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 

El siguiente código publica un mensaje que mi suscriptor debería recibir (pero no recibe):

[<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
    }

NOTA:

Lo interesante del código anterior es que cuando tengo una función de Azure ejecutándose con un ServiceBusTrigger configurado con el mismo tema y nombre de suscripción, esa función de Azure se activa cada vez que ejecuto la prueba.

  • No recibo ningún mensaje de excepción
  • La función exceptionReceivedHandler nunca se activa en mi instancia de suscriptor
  • No observo ningún error de usuario en mi panel de Azure para el recurso servicebus

Tiene éxito con un nombre de tema diferente

Si cambio el nombre del tema a "pedido por mensajería", la instancia del suscriptor recibe mensajes:

[<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
    }

Aquí está la suscripción que tiene el ajuste del nombre del tema:

[<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

Estos son los dos temas en mi Portal de Azure: ingrese la descripción de la imagen aquí

Hacer clic en Temas en el portal tiene diferentes resultados:

Noté que tengo que hacer clic en "mensajería aceptada" dos veces solo para ver sus suscripciones. Sin embargo, puedo hacer clic en "pedido por mensajería" una vez e inmediatamente ver sus suscripciones.

Scott Nimrod
fuente
1
I don't receive any exception messages¿Tal vez porque te estás tragando las excepciones? Veo un with _bloque después de tryuno
user1623521
Observé una excepción después de crear una suscripción adicional para el tema aceptado por el servicio de mensajería, lancé el suscriptor con un valor de suscripción que coincide con el que acabo de registrar en el portal y luego eliminé la suscripción creada recientemente mientras el suscriptor aún se está ejecutando.
Scott Nimrod
No puedo reproducir su problema de mi lado, parece que conoció el comportamiento anormal en el portal del bus de servicio. Tal vez podría enviar un ticket de soporte al equipo SB.
Jay Gong
Ayer envié un boleto.
Scott Nimrod

Respuestas:

0

Si entiendo correctamente que intentaste eliminar el tema problemático y volver a crearlo, me parece un problema en Azure. No debe obtener el comportamiento descrito anteriormente donde se debe hacer clic dos veces. A veces he creado cosas en Azure, hay un problema en algún lugar aguas abajo de su infraestructura, y una solicitud de soporte es la única forma de resolverlo.

Jayme Edwards
fuente