How to call Azure service fabric remoting proxy with CancellationToken?

905 views Asked by At

Based on the documentation sample, the proxy is created like this:

IMyService helloWorldClient = ServiceProxy.Create<IMyService>(new 
Uri("fabric:/MyApplication/MyHelloWorldService"));

string message = await helloWorldClient.HelloWorldAsync();

But providing I need to limit the max amount of response time I would normally create CancellationToken and pass it down to the call. Is there a way how to pass the token to proxy so it cancels waiting for the result from remote service?

3

There are 3 answers

0
dharshana jagoda On

You can do this in V2 stack, I haven't tried the V1 stack but it might work there too. Add a parameter of CancellationToken type to the method signature:

void HelloWorldAsync(CancellationToken cancellationToken);

this token will then get passed to ServicePartitionClient.InvokeWithRetryAsync method via the proxy.

The generated proxy method will look like the following:

Task<string> IMyService.HelloWorldAsync(CancellationToken cancellationToken)
{
    IServiceRemotingRequestMessageBody serviceRemotingRequestMessageBody = base.CreateRequestMessageBodyV2("MyNamespace.IMyService", "HelloWorldAsync", 1);
    Task<IServiceRemotingResponseMessageBody> task = base.InvokeAsyncV2(
    1, -1, "HelloWorldAsync", serviceRemotingRequestMessageBody,
    cancellationToken);
    return base.ContinueWithResultV2<ServiceInfoResponse>(task);
}

Without the CancellationToken parameter the proxy method looks like:

Task<string> IMyService.HelloWorldAsync()
{
    IServiceRemotingRequestMessageBody serviceRemotingRequestMessageBody = base.CreateRequestMessageBodyV2("MyNamespace.IMyService", "HelloWorldAsync", 1);
    Task<IServiceRemotingResponseMessageBody> task = base.InvokeAsyncV2(
    1, -1, "HelloWorldAsync", serviceRemotingRequestMessageBody,
    CancellationToken.None);
    return base.ContinueWithResultV2<ServiceInfoResponse>(task);
}

If you want to inspect the generated proxy assembly use the following attribute in the EntryPoint assembly or the assembly that has the service interface defined:

[assembly: CodeBuilder(EnableDebugging = true)]
0
Diego Mendes On

As far I can tell, is not possible to do it passing a cancellation token to the calls, because it is just a proxy and it will only accept parameters for the methods you describe in your interfaces.

To accomplish what you want, Cancel an operation after a certain time, you have to configure the FabricTransportRemotingListenerSettings and set the OperationTimeout to the desired timeout. The default is 5 minutes.

You can also do this setting via TransportSettings in the service settings.xml.

The following link will show both examples of how to set FabricTransportRemotingListenerSettings or TransportSettings configurations. https://learn.microsoft.com/en-us/azure/service-fabric/service-fabric-reliable-services-secure-communication

The documentation does not show, but the parameter you have to set is: OperationTimeout

The same can be done for actors, see here, pay attention that for actors some settings are different.

0
swcraft On

To whom still interested in properly doing what this thread is asking, could below link be the answer?

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

Content:

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.