state manager parallel transactions in runasync

236 Views Asked by At

In service fabric stateful services, there is RunAsync(cancellationToken) with using() for state manager transaction.

The legacy code I want to refactor contains two queues with dequeue attempts inside the while(true) with 1 second delay. I would like to get rid of this unnecessary delay and instead use two distinct reactive queues (semaphores with reliable queues).

The problem is, now the two distinct workflows depending on these two queues need to be separated into two separate threads because if these two queues run in single thread one wait() will block the other code from running. (I know probably best practice would separate these two tasks into two microservices, next project.)

I came up with below code as a solution:

    protected override async Task RunAsync(CancellationToken cancellationToken)
    {
        await Task.WhenAll(AsyncTask1(cancellationToken), AsyncTask2(cancellationToken)).ConfigureAwait(false);
    }

And each task contains something like:

    while (true)
    {
        cancellationToken.ThrowIfCancellationRequested();

        using (var tx = this.StateManager.CreateTransaction())
        {
            var maybeMessage = await messageQueue.TryDequeueAsync(tx, cancellationToken).ConfigureAwait(false);

            if (maybeMessage.HasValue)
            {
                DoWork();
            }

            await tx.CommitAsync().ConfigureAwait(false);
        }
    }

Seems working but I just want to make sure if the using(statemanger.createTansaction()) is ok to be used in this parallel way..

1

There are 1 best solutions below

3
On BEST ANSWER

According to documentation

Depending on the replica role for single-entry operation (like TryDequeueAsync) the ITransaction uses the Repeatable Read isolation level (when primary) or Snapshot isolation level (when **secondary).


Repeatable Read

Any Repeatable Read operation by default takes Shared locks.

Snapshot

Any read operation done using Snapshot isolation is lock free.


So if DoWork doesn't modifies the reliable collection then multiple transaction can be executed in parallel with no problems.

In case of multiple reads / updates - this can cause deadlocks and should be done with care.