我有一个无状态服务在RunAsync方法中运行后台进程。
此后台进程必须永远运行。它的作用是无关紧要的,但它基本上每60秒轮询一次数据库。
与Worker Role或WebJob不同,Service Fabric服务中的RunAsync方法可以运行完成,服务实例也会保持运行。
当Service Fabric发出传递给RunAsync的取消令牌信号时,就会发生这种情况。
一旦Service Fabric决定从RunAsync方法正常返回,我该如何重新运行我的轮询例程呢?
我如何确定Service Fabric首先发出取消令牌的原因?
我目前的解决方法是抛出异常,以便强制重启服务。
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);
}
}
}
}
}
答案 0 :(得分:0)
您是否可以让轮询方法返回Task<T>
而不是Task
?您可以在您选择的对象中返回原因。
答案 1 :(得分:0)
一旦Service Fabric决定从RunAsync方法正常返回,我该如何重新运行我的轮询例程呢?
据我所知,一旦返回RunAsync将再次被调用。 在Reliable services lifecycle overview上,您可以阅读以下内容。
对于有状态的可靠服务,如果服务从主服务器降级然后升级回主服务器,则会再次调用RunAsync()。
您还可以在那里阅读降级和升级的主要副本的生命周期,其中不包括OnCloseAsync。
我如何确定Service Fabric首先发出取消令牌的原因?
我担心您需要搜索抛出的异常。请注意,我不确定这个答案,这只是我的怀疑。