I have a stateless service running a background process inside RunAsync method.
This background process must run forever. What it does is irrelevant, but it essentially polls a database every 60 seconds.
Unlike a Worker Role or WebJob, the RunAsync method in a Service Fabric service can run to completion and the service instance will stay up.
This has been observed to happen when Service Fabric signals the cancellation token passed to RunAsync.
Once Service Fabric decides to gracefully return from RunAsync method, how can I rerun my polling routine again?
And how can I determine why Service Fabric signalled cancellation token in the first place?
My current workaround is to throw an exception so the service is forced to restart.
public class Stateless1 : StatelessService
{
protected override async Task RunAsync(CancellationToken cancellationToken)
{
try
{
await Start(cancellationToken);
}
catch(OperationCanceledException ex)
{
throw;
//If an OperationCanceledException escapes from
//RunAsync(CancellationToken) and Service Fabric runtime has requested
//cancellation by signaling cancellationToken passed to
//RunAsync(CancellationToken), Service Fabric runtime handles this exception and
//considers it as graceful completion of RunAsyn(CancellationToken).
}
catch(Exception ex)
{
// log error
throw;
// force service to restart, If an exception of any other type escapes from
// RunAsync(CancellationToken) then the process that is hosting this service
// instance is brought down
}
}
private async Task Start(CancellationToken cancellationToken)
{
while(true)
{
cancellationToken.ThrowIfCancellationRequested(); // honour cancellation token
try
{
await PollDatabase();
}
catch(Exception ex)
{
// log error
throw;
}
finally
{
for (var i = 0; i < 12; i++)
{
cancellationToken.ThrowIfCancellationRequested(); // honour cancellation token
await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken);
}
}
}
}
}