azure-service-fabric - cancelToken.IsCancellationRequested 在服务结构的滚动升级中不成立
问题描述
我有一个状态完整的服务,它正在扫描一个可靠的集合并对其执行一些操作。RunAsync 中的代码如下:
while (!cancellationToken.IsCancellationRequested)
{
try
{
var cacheItemsWithExpiration = await this.cacheStore.GetAllCacheItemsWithExpiration(); // Call to reliable collection
// some processing on cacheItemsWithExpiration
}
catch (Exception ex)
{
this.telemetryHelper.TrackException(ex); // Telemetry logging
}
}
现在,在滚动升级期间,GetAllCacheItemsWithExpiration 方法会引发错误"Primary State Manager is current not readable"。
现在根据编写的代码,在异常之后 while 循环应该退出,因为我认为升级将发送取消。但不知何故,它卡在了那个循环中并继续记录异常。
我在 Service Fabric 资源管理器中看到以下消息:
解决方案
如屏幕截图所示,错误发生在辅助副本中,根据消息,看起来它正在尝试切换角色,其中主副本变为辅助副本,反之亦然。
SwapPrimary重新配置发生在升级必须放下实例以带来新版本时,并且当它发生在主要副本上时,其中一个次要被提升为主要。
如您所见,这只是一个警告,可能发生的情况是您的代码在循环之间花费了太长时间才能完成,直到您再次检查取消,可能GetAllCacheItemsWithExpiration()
花费的时间太长或者代码仍在处理之后当交换发生时。
您可以尝试:
- 检查取消令牌是否被正确取消
- 检查您的方法中的取消
GetAllCacheItemsWithExpiration()
- 返回方法后检查取消
- 检查可能导致进程挂起一段时间的所有地方
在最后一种情况下,您可能希望OnChangeRoleAsync(ReplicaRole newRole, CancellationToken cancellationToken)
从有状态服务中实现覆盖以跟踪角色更改,请在此处查看更多详细信息