rebus-org / Rebus.PostgreSql

:bus: PostgreSQL persistence for Rebus
https://mookid.dk/category/rebus
Other
18 stars 20 forks source link

Request: IExclusiveAccessLock Implementation #48

Open alexhelms opened 1 month ago

alexhelms commented 1 month ago

I have an application using rebus sagas. There are two application instances and a shared database. I'm getting ConcurrencyExceptions when trying to handle a saga message.

Rebus.Exceptions.ConcurrencyException: Update of saga with ID d20e4436-fcd3-448c-a7ac-973661e1dc2e did not succeed because someone else beat us to it
   at Rebus.PostgreSql.Sagas.PostgreSqlSagaStorage.Update(ISagaData sagaData, IEnumerable`1 correlationProperties)
   at Rebus.Sagas.LoadSagaDataStep.SaveSagaData(RelevantSagaInfo sagaDataToUpdate, Boolean insert)
   at Rebus.Sagas.LoadSagaDataStep.SaveSagaData(RelevantSagaInfo sagaDataToUpdate, Boolean insert)
   at Rebus.Sagas.LoadSagaDataStep.Process(IncomingStepContext context, Func`1 next)
   at Rebus.Sagas.Exclusive.EnforceExclusiveSagaAccessIncomingStepBase.Process(IncomingStepContext context, Func`1 next)
   at Rebus.Sagas.Exclusive.EnforceExclusiveSagaAccessIncomingStepBase.Process(IncomingStepContext context, Func`1 next)
   at Rebus.Pipeline.Receive.ActivateHandlersStep.Process(IncomingStepContext context, Func`1 next)
   at Rebus.Pipeline.Receive.HandleRoutingSlipsStep.Process(IncomingStepContext context, Func`1 next)
   at Rebus.Pipeline.Receive.DeserializeIncomingMessageStep.Process(IncomingStepContext context, Func`1 next)
   at Rebus.DataBus.ClaimCheck.HydrateIncomingMessageStep.Process(IncomingStepContext context, Func`1 next)
   at Rebus.Pipeline.Receive.HandleDeferredMessagesStep.Process(IncomingStepContext context, Func`1 next)
   at Rebus.Retry.Simple.DefaultRetryStep.Process(IncomingStepContext context, Func`1 next)

It is my understanding that I need to have each application instance acquire a distributed lock which means configuring the bus to use a IExclusiveAccessLock. I'm noticing that rebus postgresql doesn't yet have an implementation. I'm not an expert in this so the best I could do would be to copy the MySQL implementation but for postgres. Does that seem appropriate? If not what is a path forward? Thanks!

mookid8000 commented 1 month ago

That would definitely be a good way to approach this. If you need inspiration for the mechanisms to use in Postgres for locking, I am sure the excellent DistributedLock library has some good reference code.