Cómo asegurar el orden de recepción de mensajes en MassTransit

tengo una saga que tiene 3 estados; Inicial, Filas de recepción, Completado -

    public static State Initial { get; set; }
    public static State ReceivingRows { get; set; }
    public static State Completed { get; set; }

Pasa de Inicial a Filas de recepción cuando recibe un BofMessage (donde Bof = Comienzo del archivo). Después del BofMessage, recibe una gran cantidad de RowMessages donde cada uno describe una fila en un archivo sin formato. Una vez que se envían todos los RowMessage, se envía un EofMessage y el estado cambia a Completado. observar -

    static void DefineSagaBehavior()
    {
        Initially(When(ReceivedBof)
            .Then((saga, message) => saga.BeginFile(message))
            .TransitionTo(ReceivingRows));

        During(ReceivingRows, When(ReceivedRow)
            .Then((saga, message) => saga.AddRow(message)));

        During(ReceivingRows, When(ReceivedRowError)
            .Then((saga, message) => saga.RowError(message)));

        During(ReceivingRows, When(ReceivedEof)
            .Then((saga, message) => saga.EndFile(message))
            .TransitionTo(Completed));
    }

Esto funciona, excepto que a veces se reciben varios RowMessages antes el BofMensaje! Esto es independientemente del orden en que les envié. Esto significa que los mensajes se recibirán y, en última instancia, se contarán como errores, lo que provocará que falten en la base de datos o en el archivo en el que finalmente los escribo.

Como solución temporal, agrego un pequeño truco de temporizador de suspensión en este método que hace toda la publicación:

    public static void Publish(
        [NotNull] IServiceBus serviceBus,
        [NotNull] string publisherName,
        Guid correlationId,
        [NotNull] Tuple<string, string> inputFileDescriptor,
        [NotNull] string outputFileName)
    {
        // attempt to load offsets
        var offsetsResult = OffsetParser.Parse(inputFileDescriptor.Item1);
        if (offsetsResult.Result != ParseOffsetsResult.Success)
        {
            // publish an offsets invalid message
            serviceBus.Publish<TErrorMessage>(CombGuid.Generate(), publisherName, inputFileDescriptor.Item2);
            return;
        }

        // publish beginning of file
        var fullInputFilePath = Path.GetFullPath(inputFileDescriptor.Item2);
        serviceBus.Publish<TBofMessage>(correlationId, publisherName, fullInputFilePath);

        // HACK: make sure bof message happens before row messages, or else some row messages won't be received
        Thread.Sleep(5000);

        // publish rows from feed
        var feedResult = FeedParser.Parse(inputFileDescriptor.Item2, offsetsResult.Offsets);
        foreach (var row in feedResult)
        {
            // publish row message, unaligned if applicable
            if (row.Result != ParseRowResult.Success)
                serviceBus.Publish<TRowErrorMessage>(correlationId, publisherName, row.Fields);
            else
                serviceBus.Publish<TRowMessage>(correlationId, publisherName, row.Fields);
        }

        // publish end of file
        serviceBus.Publish<TEofMessage>(correlationId, publisherName, outputFileName);
    }

Es un temporizador para dormir de 5 segundos y es un truco bastante feo. ¿Alguien puede informarme por qué no recibo los mensajes en el orden en que los envío? ¿Puedo asegurarme de que estos mensajes se envíen en el orden correcto si no están ordenados de forma predeterminada?

¡Gracias!

Tenga en cuenta que esto es una publicación cruzada de http://groups.google.com/group/masstransit-discuss/browse_thread/thread/7bd9518a690db4bb por conveniencia

preguntado el 22 de mayo de 12 a las 19:05

1 Respuestas

No puede asegurarse de que los mensajes se entreguen en cualquier orden. Puede acercarse en MT asegurándose de que solo haya un consumidor concurrente en el lado del consumidor, todavía no dependería de este comportamiento (http://docs.masstransit-project.com/en/latest/overview/keyideas.html#handlers). Esto efectivamente haría que su consumidor tuviera un solo subproceso.

Respondido el 26 de Septiembre de 13 a las 07:09

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.