在服务结构服务中存储取消令牌

store cancellation tokens in service fabric services

我正在尝试在 Service Fabric 有状态服务中实现取消任务功能。

计划正在使用取消令牌将通知传播到 linked 线程/任务。

问题是,虽然有这些很长的 运行 任务和线程在等待这个信号,但我不确定如何根据另一个 Web API 调用找到正确的取消标记。

我在考虑使用可靠的字典,然后甚至在尝试之前,我认为这会遇到死胡同,因为 cancellationToken 无法序列化/反序列化。

请帮我解决这个问题。

Update(我不想创建一个新线程丢失此线程中提到的一些重要上下文,因此在此 post 中更新)

已确认下面的 link 描述确实显示可靠的服务和参与者方法可以支持取消令牌。然而,典型的用例是直接通过 Web API 接收取消请求,用户触发(例如点击刷新、转到另一个页面等)。在这种情况下,完全相同的端点需要接收请求,而之前的 http 请求正在处理一些较长的 运行 任务或卡住。这不是这个线程中的场景。

来自 link:https://blogs.msdn.microsoft.com/azureservicefabric/2016/02/23/service-fabric-sdk-v1-5-175-and-the-adoption-of-virtual-machine-scale-sets/

CancellationToken 支持 IService/IActor

Reliable Service 和 Reliable Actor 方法现在支持可以通过 ActorProxy 和 ServiceProxy 远程执行的取消令牌,从而允许您实施合作取消。想要取消长 运行 服务或参与者方法的客户端可以发出取消令牌信号,并且取消意图将传播到 actor/service 方法。然后该方法可以通过查看其取消令牌参数的状态来确定何时停止执行。

例如,一个参与者的合约可能有一个 long-运行 方法可以建模如下:

        public interface IPrimeNumberActorInterface : IActor
        {

            Task<ulong> FindNextPrimeNumberAsync
                (ulong previous, CancellationToken cancellationToken);

        }

希望取消方法执行的客户端代码可以通过取消取消标记来传达其意图。

CancellationToken & CancellationTokenSource 不可序列化,并且不会在 SF 中跨服务调用或数据复制流动。它只能用于告诉同一进程中的处理程序操作已被取消并且应该停止任何处理或忽略任何继续以防收到响应。

如果您希望能够在另一个服务中启动和取消操作,您应该将操作拆分为两个调用。

  • 首先会生成一个Operation ID返回给客户端,然后为这个operation创建一个CancellationTokenSource生成一个CancellationToken传递给Task\Thread运行 在后台
  • 第二个将接收 OperationID 并确定 CancellationTokenSource 是否存在并取消它,以便提供给任何 Task\Thread 的令牌可以停止任何处理,如果尚未完成或取消。

您可以简单地将其作为 Dictionary<Guid, CancellationTokenSource> 存储在 process\partition 运行 任务中。

如果你在 SF 的多个分区中 运行 这些任务,并计划将其存储在 Reliable Dictionary 中,这不是一个好主意,因为如前所述,你无法序列化取消到其他分区。

在这种情况下,您可以存储 OperationID 和 PartitionID,因此所有分区都知道操作在哪里 运行,当您收到任何分区的取消调用时,服务将在此查找操作为 运行 的可靠字典,并将取消转发到正确的分区。