-
-
Notifications
You must be signed in to change notification settings - Fork 364
Thread safety and instance policies
Rebus is generally structured in a way so that you - as a developer of applications that send/publish and handle messages - do NOT have to worry about thread safety and race conditions etc.
On this page, you can find a few words about how this is implemented in the different areas of Rebus.
The bus instance (i.e. whatever sits behind the IBus
reference passed to you as a result of calling the entire Configure.With(...)
spell, which is the same instance as the one you can resolve from your IoC container if you use one of those) is fully reentrant and can safely be called from multiple threads.
Unless your bus is a one-way client, the bus instance will "host" a number of worker threads, and the bus instance will be the root of this object graph.
As such, the bus instance is often best kept as a SINGLETON in your IoC container, or as a static instance somewhere in your application.
If you have more than one input queue (i.e. you're hosting multiple endpoints) in the same process, you will of course have a bus instance per endpoint - but you will probably never have multiple bus instances per input queue in the same process, because that kind of concurrency would be better achieved by configuring a higher number of threads and/or level of parallelism.
When you create a bus instance using the Configure.With(...)
syntax, you will most likely be using an IoC container via one of the adapters provided by Rebus.
If you're using Microsoft's hosting model, you'll most likely want to use the Rebus.ServiceProvider package and initiate the configuration by calling services.AddRebus(...);
The configuration API will insert the bus instance (an instance of a class that implements IBus
) into the container as a singleton, and it will do so in a way that ensures that the bus is disposed when the container is disposed. This means that you should be sure to dispose the container when your application exists.
If you prefer, you CAN also just go ahead and dispose the bus instance when your application exits - nothing bad will happen if it was somehow disposed more than once.
When a message is received, it is dispatched to your message handler(s).
Since the IHandleMessages<TMessage>
does not imply any kind of statefulness, you can reuse handler instances if you like. It is advised though, to configure your IoC container to create new handler instances each time they are resolved, in order to avoid mixing them up with SAGA HANDLERS (whose instances must never be reused!)
With some containers (e.g. Castle Windsor and others) this is called "a transient lifestyle".
A saga handler is a class that - in addition to implementing one or more IHandleMessages<TMessage>
interfaces - is derived from Saga<TSagaData>
, which DOES carry with it some state (that is the entire purpose of a saga - to bring some statefulness into play).
It is absolutely imperative that your saga handlers are configured with a transient lifestyle (i.e. new instances will be created each time the container is asked to resolve), because otherwise the saga data instance on the Data
property of the saga handler will suddenly no longer be used by a single thread only.
Basic stuff
- Home
- Introduction
- Getting started
- Different bus modes
- How does rebus compare to other .net service buses?
- 3rd party extensions
- Rebus versions
Configuration
Scenarios
Areas
- Logging
- Routing
- Serialization
- Pub sub messaging
- Process managers
- Message context
- Data bus
- Correlation ids
- Container adapters
- Automatic retries and error handling
- Message dispatch
- Thread safety and instance policies
- Timeouts
- Timeout manager
- Transactions
- Delivery guarantees
- Idempotence
- Unit of work
- Workers and parallelism
- Wire level format of messages
- Handler pipeline
- Polymorphic message dispatch
- Persistence ignorance
- Saga parallelism
- Transport message forwarding
- Testing
- Outbox
- Startup/shutdown
Transports (not a full list)
Customization
- Extensibility
- Auto flowing user context extensibility example
- Back off strategy
- Message compression and encryption
- Fail fast on certain exception types
Pipelines
- Log message pipelines
- Incoming messages pipeline
- Incoming step context
- Outgoing messages pipeline
- Outgoing step context
Prominent application services