Subscription Model

The term ‘subscription’ in Reactor Service Bus is a bit overloaded. It means more than the latter half of a typical pub/sub pattern. We use the term ‘subscription’ to signify any interest an endpoint has in any message type, and what channel they wish to receive it on.

Destinations

The JMS specification is written to provide two destinations on which an endpoint can receive a message. They are Topics and Queues. The diagrams below depict the standard purpose of Topics and Queues.

image

* – Typical pub/sub pattern using Topics

 

image

* – Typical point-to-point communication using Queues

 

Fairly straight forward when you look at it in terms of pub/sub or point-to-point. There are additional complexities in how each are implemented and their capabilities, such as what happens when you have multiple recipients listening to the same queue?

Important concepts surrounding Topics:

  • Used for publishing to multiple subscribers.
  • Usually better suited for time-sensitive information (think about stock quotes)
  • Not durable in nature by default. If a subscriber goes offline, it misses messages sent on the topic.
  • Can be specified as durable, meaning subscribers can still receive topic messages when they come back online.

Important concepts surrounding Queues:

  • Used for point to point communication. Only one consumer receives a given message.
  • The producer does not have to be online when the consumer processes the message.
  • Messages placed on a queue are durable.
  • Can be used to effectively load balance two listeners by delivering on a round-robin basis. More details on this approach are located in the Load Balancing section of the documentation.
  • Reliable transaction support.

As previously mentioned, the term ‘subscription’ in Reactor is overloaded and not limited to pub/sub models. Rather, it indicates an interest in a particular message type on a particular destination (Queue or Topic). In the next section, we’ll discuss how this interest is declared and formalized.

 

Declaring Subscriptions

One of the goals of Reactor Service Bus was to declare subscriptions simply by defining message handlers and not by manually calling methods to subscribe. Of course, this behavior can be overridden, where a handler opts out of automatic subscription and allows code to manually initiate a subscription. Let’s cover automatic subscriptions first.

Automatic subscriptions are achieved by simply decorating a message handler with the appropriate destination attribute. The two attributes are:

  • QueueAttribute
  • SubscriptionTopicAttribute

If a message handler does not contain one of these attributes, no automatic subscription is performed. If a destination attribute is present, a subscription is created for the specified destination and registered with the configured IDestinationRegistry instance.

Destination attributes convey destination names both implicitly and explicitly. The rules around this are simple:

  • QueueAttribute – if no queue name is specified in the attribute constructor, the primary input queue for the current endpoint is assumed. If a name is specified, a queue listener is created for the specified queue.
  • SubscriptionTopicAttribute – if no topic name is specified in the attribute constructor, a topic name of the message type (including full namespace) is assumed. If a topic name is specified, a topic listener is created for the specified topic.

Here is an example of a handler declaration that expects a “UserCreated” event message on the topic: CompanyXYZ.Events.UserCreated:

[Topic] 
public class UserCreatedHandler : IMessageHandler<CompanyXYZ.Events.UserCreated> 
{ 
    // Implementation 
}

Note: The same handler decorated with the [Queue] attribute would expect messages of that type to be received on the primary input queue.

We don’t always have the luxury of creating message types whose full namespace with type name can act as a meaningful subscription topic name. For these occasions, we can override the default topic for a message like this:

[Topic("CompanyXYZ.HumanResources.Events.UserCreated")]
public class UserCreatedHandler : IMessageHandler<UserCreated>
{
    // Implementation
}

 

Similarly, overriding the implicit queue name is performed the same way as topics.

Last edited Feb 10, 2011 at 4:52 AM by akilhoffer, version 6

Comments

No comments yet.