Azure Service Fabric inter service communication

Viewed 1781

I currently have one Service Fabric application that is composed of multiple Services. What I'm trying to achieve is a Queuing mechanism so one Service can publish a message to a queue, and another Service can receive messages from the same queue.

The following doesn't work (for the Listener service, there is nothing to dequeue):

PublisherService:

protected override async Task RunAsync(CancellationToken cancellationToken)
{
    var myQueue = await StateManager.GetOrAddAsync<IReliableQueue<string>>("fooQueue");
    while (true)
    {
        cancellationToken.ThrowIfCancellationRequested();
        using (var tx = this.StateManager.CreateTransaction())
        {
            // Put some message in the queue
            await myQueue.EnqueueAsync(tx, "Foobar");

            await tx.CommitAsync();
        }

        await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
    }
}

ListenerService:

protected override async Task RunAsync(CancellationToken cancellationToken)
{
    var myQueue = await StateManager.GetOrAddAsync<IReliableQueue<string>>("fooQueue");
    while (true)
    {
        cancellationToken.ThrowIfCancellationRequested();
        using (var tx = this.StateManager.CreateTransaction())
        {
            var result = await myQueue.TryDequeueAsync(tx);

            if (result.HasValue)
            {
                ServiceEventSource.Current.ServiceMessage(this.Context, "New message receieved: {0}", result.Value.ToString());
            }

            await tx.CommitAsync();
        }

        await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
    }
}

It looks like the scope of a queue is limited to a single Service. This doesn't appear to be a limitation specified in the documentation.

So my questions are:

  • is this actually some undocumented limitation?
  • or is there something wrong in the code above?
  • how could I achieve the scenario above (one service adds messages to a queue, another service retrieves messages from the same queue)?

Obviously I could use an Azure Service Bus, but I can't for several reasons:

  • in my actual real-world scenario, I will have several queues (variable number) so it would require creating Service Bus Queues on demand (which is not exactly a fast operation)
  • adds a dependency to another Azure service (so increases the failure probability for the whole system)
  • costs more
  • more complex deployment
  • etc.
3 Answers

If you add a fault-handling retry pattern to all of your calling code, you should not need a queue in between your calls, see https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-reliable-services-communication

Relevant part from the link is here:

An exception handler is responsible for determining what action to take when an exception occurs. Exceptions are categorized into retryable and non retryable. Non retryable exceptions simply get rethrown back to the caller. retryable exceptions are further categorized into transient and non-transient. Transient exceptions are those that can simply be retried without re-resolving the service endpoint address. These will include transient network problems or service error responses other than those that indicate the service endpoint address does not exist. Non-transient exceptions are those that require the service endpoint address to be re-resolved. These include exceptions that indicate the service endpoint could not be reached, indicating the service has moved to a different node.

Related