-
-
Notifications
You must be signed in to change notification settings - Fork 364
Idempotence
Idempotence (which you may read a formal definition of on Wikipedia), when we are talking about messaging, is when a message re-delivery can be handled without ending up in an unintended state.
Since we always run the risk of processing the same message twice, it is a good idea to think a little bit about idempotence from time to time.
Please read the page about delivery guarantees if it is not clear at this point why we might process the same message twice.
So how do we deal with the risk of receiving the same message twice?
Generally, the best way to deal with message re-deliveries is to make the processing of each message naturally idempotent.
Natural idempotence arises when the processing of a message consists of calling an idempotent method on a domain object, like
obj.MarkAsDeleted();
or
obj.UpdatePeriod(message.NewPeriod);
or something like that, or if the processing of the message is of the upsert type, e.g. like
var itemRows = message.Items.Select(i => new ItemRow(i.Id, i.Name));
await debaser.Upsert(itemRows);
(in this case using the nifty Debaser library to do that, but some manually written SQL with appropriate unique constraints can do the trick too...)
You can come a long way, simply by making much of your message handler code idempotent like this.
When a message can be re-delivered, and it follows from the order of operations when handling a message that we are unsure whether any outgoing messages were sent, you must always ensure that outgoing sent and published messages are sent and published every time, even though the processing of a message can be identified as a re-delivery.
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