I am moving a calculation engine from an Azure worker role into Azure Service Fabric. It works by listening for messages on a Service Bus that it then processes based on the message content.
Currently, the calculation is working correctly but if the compute is taking longer than a minute or so the message does not get removed from the queue after completion. In the worker role, we solved this by increasing the "AutoRenewTimeout".
var options = new OnMessageOptions { AutoComplete = true, AutoRenewTimeout = TimeSpan.FromMinutes(3) };
_queueClient.OnMessage(OnMessage, options);
However, using the "ServiceFabric.ServiceBus" nuget package, I cannot work out where you would set this. I have used the demo project as a reference to set up a stateless service that actually runs the compute. Below is an extract from CalculateService.cs where the Stateless Service is initialised.
internal sealed class CalculateService : StatelessService
{
public CalculateService(StatelessServiceContext context)
: base(context)
{ }
/// <summary>
/// Optional override to create listeners (e.g., TCP, HTTP) for this service replica to handle client or user requests.
/// </summary>
/// <returns>A collection of listeners.</returns>
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
string serviceBusQueueName = CloudConfigurationManager.GetSetting("QueueName");
yield return new ServiceInstanceListener(context => new ServiceBusQueueCommunicationListener(new Handler(this), context, serviceBusQueueName), "StatelessService-ServiceBusQueueListener");
}
}
internal sealed class Handler : AutoCompleteServiceBusMessageReceiver
{
protected override Task ReceiveMessageImplAsync(BrokeredMessage message, CancellationToken cancellationToken)
{
ServiceEventSource.Current.ServiceMessage(_service, $"Handling queue message {message.MessageId}");
var computeRole = new ExcelCompute();
var rMessage = new RangeMessage();
rMessage = message.GetBody<RangeMessage>();
var result = computeRole.OnMessage(rMessage, message.MessageId); //returns true if the compute was successful (which it currently, always is)
return Task.FromResult(result);
}
}
I did try using the <BrokeredMessage> message.Complete();
but that was throwing a message lock error.