question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

ConsumeContext not available in Send/PublishContext

See original GitHub issue

Is this a bug report?

Yes (probably)

Can you also reproduce the problem with the latest version?

Yes

Environment

  1. Microsoft Windows 10 Pro
  2. Visual Studio 2019 (16.1.3)
  3. dotnet 2.2.103

Steps to Reproduce

using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using GreenPipes;
using MassTransit;
using MassTransit.SendPipeSpecifications;
using MassTransit.TestFramework;
using Xunit;

namespace MyMassTransitTests
{
    public class MassTransitTests : InMemoryTestFixture, IAsyncLifetime
    {
        private class MySendFilter<TMessage> : IFilter<SendContext<TMessage>> where TMessage : class
        {
            public async Task Send(SendContext<TMessage> context, IPipe<SendContext<TMessage>> next)
            {
                var msg = context.Message;

                if (context.TryGetPayload(out ConsumeContext cc))
                {
                    // I'd expect to enter this block when I send a message form within ConsumeContext
                    // i.e. in case of A message it should be bypassed, but in case of B message should be entered
                }

                await next.Send(context);
            }

            public void Probe(ProbeContext context) { context.CreateScope("my-send-filter"); }
        }

        private class ConsumerA : IConsumer<A>
        {
            public async Task Consume(ConsumeContext<A> context)
            {
                await context.Send(new B());
            }
        }

        private class ConsumerB : IConsumer<B>
        {
            public Task Consume(ConsumeContext<B> context)
            {
                return Task.CompletedTask;
            }
        }

        [Fact]
        public async Task RunTest()
        {
            EndpointConvention.Map<B>(InputQueueAddress);

            await InputQueueSendEndpoint.Send(new A());

            await Task.Delay(60000);
        }

        // Boring, start-up code below

        public MassTransitTests() : base(true) { }
        public Task InitializeAsync() => SetupInMemoryTest();
        public Task DisposeAsync() => TearDownInMemoryTest();

        private class A { }

        private class B { }

        protected override void ConfigureInMemoryBus(IInMemoryBusFactoryConfigurator configurator)
        {
            configurator.ConfigureSend(spc =>
            {
                spc.ConnectSendPipeSpecificationObserver(new MySendPipeSpecObserver());
            });
        }

        protected override void ConfigureInMemoryReceiveEndpoint(IInMemoryReceiveEndpointConfigurator configurator)
        {
            configurator.Consumer<ConsumerA>();
            configurator.Consumer<ConsumerB>();
        }

        private class MySendPipeSpecObserver : ISendPipeSpecificationObserver
        {
            public void MessageSpecificationCreated<T>(IMessageSendPipeSpecification<T> specification) where T : class
            {
                specification.AddPipeSpecification(new MySendPipeSpec<T>());
            }
        }

        private class MySendPipeSpec<TMessage> : IPipeSpecification<SendContext<TMessage>> where TMessage : class
        {
            public void Apply(IPipeBuilder<SendContext<TMessage>> builder)
            {
                builder.AddFilter(new MySendFilter<TMessage>());
            }

            public IEnumerable<ValidationResult> Validate() => Enumerable.Empty<ValidationResult>();
        }
    }
}

Expected Behavior

Having simple SendContext filter added to the pipeline, I’d expect that ConsumeContext should be available from within the filter when we’re actually sending something from consumer (message B in case of example above).

Actual Behavior

ConsumeContext is not available.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:11 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
Crozincommented, Jun 26, 2019

Sorry it me so long to reply. I’ve edited my previous comment with a proper test.

0reactions
phatboygcommented, Jul 19, 2019

This was hard, but made me seriously rethink how the Outbox works, and how contexts are related. And I think I have it in a much better place now, so thanks!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Getting ConsumeContext not available when using ...
The solution to this turned out to be using this: .Then(context => context.Raise(SomeEvent)). instead of this: .Then(context => this.
Read more >
Upgrading · MassTransit
When the ConsumeContext is owned by another component, the library only copies necessary data such as headers, payloads, and source address. This change...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found