rebus-org / Rebus.RabbitMq

:bus: RabbitMQ transport for Rebus
https://mookid.dk/category/rebus
Other
65 stars 45 forks source link

How can I get RebusHeaders exchange in RabbitMQ via Rebus? #119

Closed galloglach closed 7 months ago

galloglach commented 7 months ago

What do I need to do to get a RebHeaders exchange created in RabbitMQ when using Rebus. I can get a RebusTopics exchange created which is of type "topic". image

mookid8000 commented 7 months ago

Rebus doesn't support headers exchanges. 😐

What did you want to use it for?

galloglach commented 7 months ago

Topics exchange seems to be too restrictive, where there is just the one string that the queues bind by. The Headers exchange seems to be more flexible in that a message is published to the exchange with x different header values and queues can bind on a specific header value via "x-any".

mookid8000 commented 7 months ago

Topics exchange seems to be too restrictive, where there is just the one string that the queues bind by.

A queue can bind to lots of topics by going

await bus.Subscribe<FirstEvent>();
await bus.Subscribe<SecondEvent>();
await bus.Subscribe<ThirdEvent>();

(thus receiving events from anyone doing await bus.Publish(new FirstEvent());, await bus.Publish(new SecondEvent());, or await bus.Publish(new ThirdEvent());)

and it can even bind by anything you want by going

await bus.Advanced.Topics.Subscribe("whatever1");
await bus.Advanced.Topics.Subscribe("whatever2");
await bus.Advanced.Topics.Subscribe("whatever3");

(thus receiving events from anyone publishing to those topics via await bus.Advanced.Topics.Publish("whatever1", whatever);, await bus.Advanced.Topics.Publish("whatever2", whatever);, or await bus.Advanced.Topics.Publish("whatever3", whatever);)

What did you want to use a headers exchange for?

galloglach commented 7 months ago

An Event has a characteristic such as Date and depending on it value I'd like it to go to different queues (possibly multiple). For instance, if there were 4 queues, Within24Hours, Within7Days, Within30Days & Within365Days, the same Event message would go to the appropriate queues.

So for an Event that is occurring in 6 hours time then it would go to all the queues. An Event that is occurring in 2 weeks time then it would only go to the Within30Days & Within365Days queues.

In scenario 1 (6 hours) the message would be published with these header values { Within24Hours:1, Within7Days:1, Within30Days:1, Within365Days:1 }. In scenario 2 (2 weeks) the header values would be { Within30Days:1, Within365Days:1 }.

mookid8000 commented 7 months ago

Ok, interesting. 🙂

But yeah, you can't do that with Rebus, because Rebus doesn't support RabbitMQ's headers exchange.

Rebus is more of a "smart endpoints, dumb pipes" type of library, thus encouraging that rules and decisions be pushed closer to the application logic, instead of being implemented by features in the infrastructure

This is a great approach in many ways, because it makes the code less dependent on specific infrastructure, and it often makes the code much easier to verify in automated tests.

For Rebus it means that only a common subset of features is implemented (and sometimes polyfilled, e.g. when using Amazon SQS or Azure Storage Queues, you'll need some kind of subscription storage to enable pub/sub messaging).

To solve your problem with Rebus, you could implement some kind of content-based router in several ways, e.g. like the solution I am sketching here on StackOverflow: https://stackoverflow.com/a/40697803/6560

Closing for now. Let me know if you need any more help towards an acceptable solution 🙂

galloglach commented 7 months ago

Thanks for that info, it gives me another avenue to explore.

Just one follow up question :-)

It looks like I should be able to create a HeadersExchange (MyHeaders) in RabbitMQ, bind it to the RebusTopics exchange using the # routing pattern and then have the queues (Within24Hours, Within7Days, Within30Days_ & Within365Days) bind to MyHeaders exchange using appropriate arguments. In that case are the headers that I send when publishing to RebusTopics sent on to MyHeaders exchange?

mookid8000 commented 7 months ago

I think so, yes 🙂 but please make sure to have integration tests in place that exercise these things in particular. Sendt fra min iPhone–Mogens Heller GrabeTorsmark 48700 HorsensDanmark+45 @. 29. feb. 2024 kl. 19.04 skrev gallowglass @.>: Thanks for that info, it gives me another avenue to explore. Just one follow up question :-) It looks like I should be able to create a HeadersExchange (MyHeaders) in RabbitMQ, bind it to the RebusTopics exchange using the # routing pattern and then have the queues (Within24Hours, Within7Days, Within30Days_ & Within365Days) bind to MyHeaders exchange using appropriate arguments. In that case are the headers that I send when publishing to RebusTopics sent on to MyHeaders exchange?

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you modified the open/close state.Message ID: @.***>