Subscribers¶
Subscribers are responsible for receiving messages from RabbitMQ and dispatching them to application logic.
They form the consumer side of the messaging infrastructure.
Overview¶
Subscribers receive messages from RabbitMQ and perform the following operations:
- Receive payload.
- Deserialize payload.
- Execute application logic.
- Complete processing.
graph LR
RabbitMQ --> Subscriber
Subscriber --> Formatter
Subscriber --> Handler
Architecture¶
The subscriber implementation is descriptor-driven.
graph TD
SubscriberBoundDescriptor
IDataFormatter
Subscriber
RabbitMQ
SubscriberBoundDescriptor --> Subscriber
IDataFormatter --> Subscriber
RabbitMQ --> Subscriber
Subscriber behavior is primarily controlled through descriptors.
Subscriber Responsibilities¶
Subscribers are responsible for:
- message reception;
- payload deserialization;
- handler execution;
- acknowledgement management;
- retry participation;
- runtime start and stop lifecycle.
Subscribers are not responsible for:
- topology definition;
- exchange design;
- routing strategy design.
Those concerns belong to descriptors.
Low-Level Construction¶
The following diagram illustrates the required dependencies.
RabbitMQ.Client v6¶
graph LR
IModel --> Subscriber
IDataFormatter --> Subscriber
SubscriberBoundDescriptor --> Subscriber
Primary channel abstraction:
IModel
RabbitMQ.Client v7¶
graph LR
IChannel --> Subscriber
IDataFormatter --> Subscriber
SubscriberBoundDescriptor --> Subscriber
Primary channel abstraction:
IChannel
Consumption Flow¶
The subscriber processing workflow is shown below.
sequenceDiagram
participant RabbitMQ
participant Subscriber
participant Formatter
participant Handler
RabbitMQ->>Subscriber: Deliver Message
Subscriber->>Formatter: Deserialize()
Formatter-->>Subscriber: Message
Subscriber->>Handler: Execute()
Handler-->>Subscriber: Result
Message Acknowledgement¶
Successful processing generally results in message acknowledgement.
sequenceDiagram
participant Subscriber
participant RabbitMQ
Subscriber->>RabbitMQ: Ack
Acknowledgements prevent messages from being redelivered.
Retry Participation¶
Subscribers are typically involved in retry workflows.
graph TD
Message
Process
Success
Failure
Retry
DeadLetter
Message --> Process
Process --> Success
Process --> Failure
Failure --> Retry
Retry --> Process
Failure --> DeadLetter
Retry behavior is configured through descriptors.
Descriptor Integration¶
Common descriptor settings include:
- queue information;
- exchange bindings;
- retry behavior;
- dead-letter configuration;
- consumer settings.
The descriptor model centralizes infrastructure concerns and keeps handlers focused on business logic.
Lifecycle¶
Subscribers implement IAsyncRunnable.
public interface IAsyncRunnable
{
bool IsRunning { get; }
Task Start();
Task Stop();
}
The subscriber is explicitly started and stopped.
await subscriber.Start();
await subscriber.Stop();
The current runtime state can be inspected through IsRunning.
if (subscriber.IsRunning)
{
Console.WriteLine("Subscriber is running.");
}
stateDiagram-v2
[*] --> Created
Created --> Running : Start()
Running --> Stopped : Stop()
Stopped --> Running : Start()
Implementations should handle repeated calls to Start() and Stop() gracefully.
Error Handling¶
Subscriber failures may be caused by:
- invalid payloads;
- deserialization issues;
- business exceptions;
- infrastructure failures.
Handling strategies typically involve:
- retries;
- dead-letter queues;
- operational monitoring.
v6 vs v7¶
| Capability | RabbitMQ.Client v6 | RabbitMQ.Client v7 |
|---|---|---|
| Channel Type | IModel | IChannel |
| Subscriber API | Supported | Supported |
| Descriptor Model | Same | Same |
| Formatter Model | Same | Same |
The framework maintains a consistent programming model across both RabbitMQ client versions.