Feature: Message Bus

Topics: Core, General
Coordinator
Sep 18, 2014 at 7:54 PM
This thread is created to discuss a new feature I'd like to include as a core module: Message Bus.

Some websites are working inside web server farms for performance and reliability reasons. Orchard works well under this scenario, with some constraints. One of them is that Settings like content type definitions, site settings, and anything which is cached can't be modified in production, or all the nodes of a farm need to be restarted.

This is a typical hosting issue, and there are typical solution to this. One is to use a message bus implementation. Message buses allow a node to send a message on a channel that another nodes can subscribe to, and act based on the message they receive. Some well-known examples are MSMQ, Azure Message Bus Services, Redis, RabitMQ, SQL Broker, ...

The strategy for Orchard would be to implement a set of APIs to send/receive any kind of messages. This infrastructure would then be used by another module to broadcast cache invalidation messages, and shell restarts. Different message bus implementations would be provided, like SQL Broker, Azure Service Bus, and Redis which should cover most of the topologies we have seen used with Orchard. Any module developer could also use the base message bus feature for their own purpose.

Overall proposed design:
Orchard.MessageBus module
Features:
  • Message Bus: Default API abstraction to send/subscribe to messages. Implementation agnostic, will require at least one concrete implementation feature.
  • Cluster Syncrhonization: This feature would broadcast Signals and Shell restart notifications to all the nodes in a farm, by using the main Message Bus APIs.
  • SQL Broker: This is a concrete implementation of the Message Bus APIs using SQL Server which has a SQL Broker service.
  • Azure Service Bus: Same idea based on Azure Service Bus. It has a cost would be free or close to free in a real usage.
  • Redis: Using Redis. It's also available on Azure. Orchard 1,9 should have a support for Caching on Redis. hence we can reuse the library.
Polling has been considered, and would not require any message bus, but there are limitations to this solution like a delay between when the message is broadcasted and delivered, and we can safely assume that any cluster installation of Orchard is at least using Sql Server, so could use the broker.

It's also worth mentioning that Zoltan (aka Piedone, aka Lombiq) has already implemented such services using polling, which validates the idea that is presented here. We might want to use his brain, if he's sharing it. c.f. https://orcharddistributedevents.codeplex.com/
Developer
Sep 18, 2014 at 10:17 PM
My brain used a lot of energy so I switched off half of it. I know you're talking to me but I don't have an idea what this Orchard is.
Sep 19, 2014 at 1:44 AM
Sebastien by farm you mean using different IIS clusters AKA (load balancing) to host a single website like ww1.domain.com, ww2.domain.com right ? If this is the type of scenario described then I presume or even assume that those are or will be using SQL Server for the same performance and reliability reasons. From what I know from these type of scenarios ; that's where a deploy feature is most likely welcome. So then you can stage your content from a developpement environment to a production environment. This is not as straightforward than your idea though.

Starting from there, we could also have a scenario in wich Orchard would be using SQL Server in clustering for performance and reliability reasons. So, I guess the message bus would need to also update databases...

Remember that perfect replication of a website from one instance to another is not just about invalidating cache. But, yes that would be a step forward. I like the idea.
Sep 30, 2014 at 10:26 PM
Edited Oct 1, 2014 at 8:19 PM
There is another important aspect to consider when you have environment in load balancing.
Jobs and tasks.

Orchard provides IBackgroundTask and IScheduledTaskHandler interfaces and we can run independend jobs/tasks in our code i. e. sending emails from queue. Tasks don't know about other instances of the same site.
If you have two or more sites in load balancing there is a high probability that something will be locked or will be done two times or more when executing the same task on each instance.
Risk of this grows when tasks use cache to retrieve part of data.

I think there should be an infrastructure which broadcasts signal to others i. e. 'Hello, I have started to execute: email sending task and you don't have to do the same'. It is used to avoid executing the same task many times.
Jan 18, 2015 at 3:35 PM
I have a Redis caching module and an Azure service bus module, the latter needs a small bug fixing but other than that happy to share the raw modules for inspiration. Let me know if you're still interested in pursuing this for 1.9.