Search code examples
c#mongodbrebus

Rebus: Should IdempotencyData be persisted along with IdempotentSagaData instance?


I'm trying to use the IdempotentSagas in Rebus with MongoDb as a storage. I enable idempotency when configuring Rebus like this:

Configure
    ...
    .Options( o => { o.EnableIdempotentSagas(); } )
    ...
    .Sagas( s => { s.StoreInMongoDb( mongoDatabase ); } )

I can see in debug that (during handling the message) the property IdempotencyData in the IdempotentSagaData instance stores the handled message id.

But when the saga data gets persisted, the IdempotencyData is always stored as an empty document:

{
    "_id" : NUUID("0aa63d69-f8f9-46bd-ab29-f1e46411a166"),
    "Revision" : 1,
    "IdempotencyData" : {},
    ...    
}

and thus it always appears empty when the saga data is loaded from the storage to handle a message.

It seems that this neglects all the idempotency checks, and later redelivered messages will be handled as if they are completely new. But the IdempotencyData class seems to be designed in a way which prevents it from being serialized by the default MongoDb BsonSerializer (get-only properties, private backing fields).

Is it an intentional behavior? Maybe I'm missing some configuration step which would allow the idempotency data to be persisted?

Thanks in advance for your help.


Solution

  • Rebus (all versions prior to Rebus 5.0.0-b14) had a BSON serializer-unfriendly IdempotencyData, thus making it impossible to properly roundtrip this pretty important piece of data when using IIdempotentSagaData.

    It has been fixed in Rebus.MongoDb 5.0.0-b02 and Rebus 5.0.0-b14.

    Rebus' IdempotencyData now has proper constructors in place, allowing for serializers to initialize the entire state that way.

    Rebus.MongoDb now registers appropriate class maps during initialization of the saga storage.