问题
I am trying to achieve cancel tasks feature in service fabric stateful services.
Plan is using cancellation token to propagate notices to linked threads / Tasks.
The problem is, while there are these long running tasks and threads waiting for this signal, I am not sure how I can find the right cancellation tokens based on another Web API calls.
I was thinking of using reliable dictionary, then even before trying it out, I assume this will hit deadend because cancellationToken can't be serialized / deserialized.
Please help me what could be good solution to solve this issue.
Update (I didn't want to create a new thread losing some of important contexts mentioned in this thread so updating in this post.)
Confirmed that below link description does show Reliable service and actor methods can support cancellation token. However typical use case would be receiving cancellation request directly via web API with user triggering such as click refresh, go to another page, etc. In such scenario, the exact same end point needs to receive the request while previous http requst is lingering with some long running task or stuck. That is not the scenario in this thread.
From 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 support for IService/IActor
Reliable Service and Reliable Actor methods now support a cancellation token that can be remoted via ActorProxy and ServiceProxy, allowing you to implement cooperative cancellation. Clients that want to cancel a long running service or actor method can signal the cancellation token and that cancellation intent will be propagated to the actor/service method. That method can then determine when to stop execution by looking at the state of its cancellation token argument.
For example, an actor’s contract that has a possibly long-running method can be modelled as shown below:
public interface IPrimeNumberActorInterface : IActor
{
Task<ulong> FindNextPrimeNumberAsync
(ulong previous, CancellationToken cancellationToken);
}
The client code that wishes to cancel the method execution can communicate its intent by canceling the cancellation token.
回答1:
CancellationToken
& CancellationTokenSource
are not serializable and doesn't flow across service calls or Data Replication in SF. It can only be used to tell the handler within the same process that an operation has been cancelled and should stop any processing or ignore any continuation in case a response is received.
If you want to be able to start and cancel an operation in another service, you should split the operation in two calls.
- The first will generate an Operation ID to be returned to the client, and Create a
CancellationTokenSource
for this operation to generate aCancellationToken
to be passed to the Task\Thread running in the background - The second will receive and OperationID and identify if a
CancellationTokenSource
exists and cancel it, so that the token provided to any Task\Thread can stop any processing, if not already completed or cancelled.
You could simply store it as a Dictionary<Guid, CancellationTokenSource>
in the process\partition running the task.
In case you are running these tasks in multiple partitions in SF, and is planning to store it in a Reliable Dictionary, it is not a good idea, because as said previously, you can't serialize the cancellation to other partitions.
In this case you can store the OperationID and the PartitionID, so all partitions know where an operation is running, when you receive a call for cancellation on any of the partitions, the service will lookup in this reliable dictionary where the operation is running and forward the cancellation to the right partition.
来源:https://stackoverflow.com/questions/52998828/store-cancellation-tokens-in-service-fabric-services