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.

EasynetQ 6.0.2 Issue

See original GitHub issue

Issue

With the upgrade to 6.0.2, i’m seeing the following issues.

  1. Exchange name for future publish not created
  2. PubSub Publish not publishing the message

For the given scenario.

In my application all the events to be published are passed through a common function as follows. In this function decision is taken to call a normal publish or future publish

public async Task Emit(IExternalEvent @event)
{

    await Bus.PubSub.PublishAsync(Convert.ChangeType(@event, @event.GetType())).ConfigureAwait(false);

    await Bus.Scheduler.FuturePublishAsync(Convert.ChangeType(@event, @event.GetType()), 
      TimeSpan.FromSeconds(DelayedTimeInSecond));
}

Since the type of @event is accepted as the implementing interface and not the concrete type, I’m casting it to the actual type as follows

Convert.ChangeType(@event, @event.GetType())

This used to work till I upgraded the library to 6.0.2

However i was able to get both working with the following changes in EasyNetQ library.

In DefaultPubSub.cs

public virtual async Task PublishAsync<T>(T message, Action<IPublishConfiguration> configure, CancellationToken cancellationToken)
        {
            Preconditions.CheckNotNull(message, "message");
            Preconditions.CheckNotNull(configure, "configure");

            using var cts = cancellationToken.WithTimeout(configuration.Timeout);

            var publishConfiguration = new PublishConfiguration(conventions.TopicNamingConvention(typeof(T)));
            configure(publishConfiguration);

            **var messageType = message.GetType(); //Modified: typeof(T);**
            var advancedMessageProperties = new MessageProperties();
            if (publishConfiguration.Priority != null)
                advancedMessageProperties.Priority = publishConfiguration.Priority.Value;
            if (publishConfiguration.Expires != null)
                advancedMessageProperties.Expiration = publishConfiguration.Expires.ToString();
            advancedMessageProperties.DeliveryMode = messageDeliveryModeStrategy.GetDeliveryMode(messageType);

            var advancedMessage = new Message<T>(message, advancedMessageProperties);
            var exchange = await exchangeDeclareStrategy.DeclareExchangeAsync(
                messageType, ExchangeType.Topic, cts.Token
            ).ConfigureAwait(false);
            await advancedBus.PublishAsync(
                exchange, publishConfiguration.Topic, false, advancedMessage, cts.Token
            ).ConfigureAwait(false);
        }

In DelayedExchangeScheduler.cs

 public async Task FuturePublishAsync<T>(
            T message,
            TimeSpan delay,
            Action<IFuturePublishConfiguration> configure,
            CancellationToken cancellationToken = default
        )
        {
            Preconditions.CheckNotNull(message, "message");
            Preconditions.CheckNotNull(configure, "configure");

            using var cts = cancellationToken.WithTimeout(configuration.Timeout);

            var publishConfiguration = new FuturePublishConfiguration(conventions.TopicNamingConvention(typeof(T)));
            configure(publishConfiguration);

            var topic = publishConfiguration.Topic;
            var exchangeName = conventions.ExchangeNamingConvention(message.GetType()); //Modified: conventions.ExchangeNamingConvention(typeof(T))
            var futureExchangeName = exchangeName + "_delayed";
            var futureExchange = await advancedBus.ExchangeDeclareAsync(
                futureExchangeName,
                c => c.AsDelayedExchange(ExchangeType.Topic),
                cts.Token
            ).ConfigureAwait(false);

            var exchange = await advancedBus.ExchangeDeclareAsync(
                exchangeName,
                c => c.WithType(ExchangeType.Topic),
                cts.Token
            ).ConfigureAwait(false);
            await advancedBus.BindAsync(futureExchange, exchange, topic, cts.Token).ConfigureAwait(false);

            var properties = new MessageProperties();
            if (publishConfiguration.Priority != null)
                properties.Priority = publishConfiguration.Priority.Value;
            properties.DeliveryMode = messageDeliveryModeStrategy.GetDeliveryMode(typeof(T));

            await advancedBus.PublishAsync(
                futureExchange, topic, false, new Message<T>(message, properties).WithDelay(delay), cts.Token
            ).ConfigureAwait(false);
        }

Please let me know if these changes are good enough. if so can this change be accepted.

Also thank you for the quick fix for the logging issue 👍

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:5 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
satishviswanathancommented, Nov 9, 2020

@Pliner I have tested with the changes that you had made in the branch non-generic-extension-for-scheduler-and-publish and it seems to be perfectly working fine with the scenarios that I have for both Publish and Future publish.

Thanks a lot for the quick changes as we had an urgent requirement for this feature. Would you be able to publish the latest version with these changes.

0reactions
Plinercommented, Nov 10, 2020

Fixed by #1148

Read more comments on GitHub >

github_iconTop Results From Across the Web

Slow EasyNetQ vs RabbitMq performance for Tasks. #661
I was just asking to update the sample above with loops and threads instead of Task, then we can try reproduce the problem...
Read more >
EasyNetQ
EasyNetQ's queue/exchange name strategy is really intuitive and simple to understand.
Read more >
Method not found
The type initializer for 'EasyNetQ.AdvancedBusEventHandlers' threw an exception. when executing RabbitHutch,CreateBus. It had no problem ...
Read more >
How to do error handling with EasyNetQ / RabbitMQ
I'm using RabbitMQ in C# with the EasyNetQ library. I'm using a pub/sub pattern here. I still have a few issues that I...
Read more >
EasyNetQ - An easy .NET API for RabbitMQ
EasyNetQ is the leading client API for RabbitMQ on .NET, with over 20 million downloads on NuGet.org. It is an open source project...
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