Singleton handler or saga

All,

We have to update an azure app configuration key which holds json array as a part of our saga workflow, we are using nsb in azure functions with azure service bus.

We are assuming that we will have to handle concurrency because when multiple saga instances try to update the same key, we might run into issues.

Is there a feature in NSB where we can make a handler or a Saga singleton ? The order of the messages really don’t matter as long as we update azure app configuration without any concurrency issues.

If the saga correlation property value is stable, e.g., update/azure/config/key, then NServiceBus will create only one saga instance and constantly reuse that whenever a message with that value triggers the saga. Effectively making the saga a singleton saga. Depending on the storage, you might also get pessimistic locking that will serialize saga access.

Mauro

thank you @mauroservienti , so basically invoking the saga with the same IAmStartedByMessage message which contains the same correlation property? something like below ??,

and we are using cosmosdb for persistence, assuming this would be suitable for this singleton scenario.

public class UpdatAppConfigSaga :
    Saga<UpdatAppConfigSagaData>,
    IAmStartedByMessages<StartAppConfigUpdate>
   
{
    static ILog log = LogManager.GetLogger<UpdatAppConfigSaga>();

    protected override void ConfigureHowToFindSaga(SagaPropertyMapper<UpdatAppConfigSagaData> mapper)
    {
        mapper.MapSaga(sagaData => sagaData.OrderId);
     }

    public Task Handle(StartAppConfigUpdate message, IMessageHandlerContext context)
    {
       // Data.OrderCount++;
        // Call the handler that updates app config.

        return Task.CompletedTask;

    }

}

Thanks - Nen

Correct, @Nen_Zax.

The IAmStartedByMessage will start the saga. If none exists, it will invoke an existing saga instance. If all messages reaching the saga have the same correlation property values, the saga will effectively be a singleton saga.

What persistence are you using?

we are using cosmos, and i am assuming we still need to call another handler from the saga to do the appconfiguration update, rather than in saga.

public class UpdatAppConfigSaga :
    Saga<UpdatAppConfigSagaData>,
    IAmStartedByMessages<StartAppConfigUpdate>
   
{
    static ILog log = LogManager.GetLogger<UpdatAppConfigSaga>();

    protected override void ConfigureHowToFindSaga(SagaPropertyMapper<UpdatAppConfigSagaData> mapper)
    {
        mapper.MapSaga(sagaData => sagaData.OrderId);
     }

    public Task Handle(StartAppConfigUpdate message, IMessageHandlerContext context)
    {

        **// Call the handler that updates app config.**

        return Task.CompletedTask;

    }

}

That’s up to you. We consider best practice not to do any concrete work in the saga and instead offload that to different handlers, so that the saga is only the state machine. But that’s not a strict rule.