Ejemplo n.º 1
0
        async Task Dispatch(CapturedTransportOperation operation, RootContext rootContext)
        {
            using (var conn = settings.Links[operation.Destination].ConnectionFactory())
            {
                await conn.OpenAsync().ConfigureAwait(false);

                using (var trans = conn.BeginTransaction())
                {
                    //Will block until the record insert transaction is completed.
                    await OutboxPersister.MarkAsDispatched(operation, conn, trans).ConfigureAwait(false);

                    var iface = settings.GetDestinationInterface(operation.Destination);

                    var chains          = rootContext.Interfaces.GetChainsFor(iface);
                    var chain           = chains.Get <AnycastContext>();
                    var dispatchContext = new OutboxDispatchContext(rootContext, iface);
                    var forwardContext  = new AnycastContext(operation.Destination, operation.OutgoingMessage, DistributionStrategyScope.Send, dispatchContext);
                    dispatchContext.Set(new TransportTransaction());
                    await chain.Invoke(forwardContext).ConfigureAwait(false);

                    //Only commit the transaction if the dispatch succeeded.
                    trans.Commit();
                }
            }
        }
Ejemplo n.º 2
0
    protected override async Task <bool> Terminate(ForwardReplyContext context)
    {
        string replyTo       = null;
        string replyToRouter = null;

        if (!context.ReceivedHeaders.TryGetValue(Headers.CorrelationId, out var correlationId))
        {
            throw new UnforwardableMessageException($"The reply has to contain a '{Headers.CorrelationId}' header set by the router connector when sending out the initial message.");
        }

        try
        {
            correlationId.DecodeTLV((t, v) =>
            {
                if (t == "reply-to")
                {
                    replyTo = v;
                }
                if (t == "id")
                {
                    context.ForwardedHeaders[Headers.CorrelationId] = v;
                }
                if (t == "reply-to-router")
                {
                    replyToRouter = v;
                }
            });
        }
        catch (Exception e)
        {
            throw new UnforwardableMessageException($"Cannot decode value in '{Headers.CorrelationId}' header: " + e.Message);
        }

        var outgoingMessage = new OutgoingMessage(context.MessageId, context.ForwardedHeaders, context.ReceivedBody);

        if (replyTo != null)
        {
            var operation = new TransportOperation(outgoingMessage, new UnicastAddressTag(replyTo));

            var chain       = context.Chains.Get <PostroutingContext>();
            var forkContext = new PostroutingContext(null, operation, context);
            await chain.Invoke(forkContext).ConfigureAwait(false);

            return(true);
        }
        if (replyToRouter != null)
        {
            var chain       = context.Chains.Get <AnycastContext>();
            var forkContext = new AnycastContext(replyToRouter, outgoingMessage, DistributionStrategyScope.Send, context);

            await chain.Invoke(forkContext).ConfigureAwait(false);

            return(true);
        }

        throw new UnforwardableMessageException("The reply contains neither \'reply-to\' nor \'reply-to-router\' correlation parameters required to route the message.");
    }
        public async Task Start(RootContext rootContext, SettingsHolder extensibilitySettings)
        {
            tokenSource = new CancellationTokenSource();

            foreach (var persister in persisters)
            {
                async Task Dispatch(OutgoingMessage operation)
                {
                    var destinationEndpoint = persister.Key;
                    var iface = destinationToInterfaceMap[destinationEndpoint];

                    var chains          = rootContext.Interfaces.GetChainsFor(iface);
                    var chain           = chains.Get <AnycastContext>();
                    var dispatchContext = new OutboxDispatchContext(rootContext, iface);
                    var forwardContext  = new AnycastContext(destinationEndpoint, operation, DistributionStrategyScope.Send, dispatchContext);

                    dispatchContext.Set(new TransportTransaction());
                    await chain.Invoke(forwardContext).ConfigureAwait(false);
                }

                await persister.Value.Start(tokenSource.Token, Dispatch);
            }
        }