Reputation: 524
I am developing a Function in Azure with Cancellation Token. Its an Http Trigger.
I pass in a Cancellation Token in in the method parameters.
Its long running function. And I cancel the request in between of the process but the process keeps running and the cancellation token doesn't take its affect.
Is this supported in Azure Functions, that if I cancel a Http Request in between it should also cancel its execution but this is not the case.
I tested this via small piece of code
public static class LongRunningFunction
{
[FunctionName("LongRunningFunction")]
public static async Task<IActionResult> RunAsync(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "Long")]
HttpRequest req, ILogger log, CancellationToken token)
{
try
{
await Task.Delay(10000, token);
return new OkResult();
}
catch (OperationCanceledException)
{
return new NotFoundResult();
}
catch (Exception e)
{
return new InternalServerErrorResult();
}
}
}
And I used Postman for the execution.
Am I doing something wrong?
I am taking help from the following Link
Upvotes: 22
Views: 15822
Reputation: 31
Heads-up Azure Functions Host release 4.20.0 resolves this issue for both In-Process and Out-Of-Process Azure Functions by tying together the application shutdown signal and the HttpContext.RequestAborted signal into a single CancellationToken (the same one that is already available in the FunctionContext).
You can read more here: https://github.com/Azure/azure-functions-host/pull/9159
Upvotes: 3
Reputation: 4279
I know this is an old question, but I found the answer to this issue.
In Azure Functions, there are 2 cancellation tokens.
The token passed in Function Method parameter is the Host Cancellation Token - cancellation is requested when the host is about to shut down.
The other token is req.HttpContext.RequestAborted
property. It's being cancelled when browser cancels the request - this is what you were after.
In addition, you can use following code:
using var cancellationSource = CancellationTokenSource.CreateLinkedTokenSource(hostCancellationToken, req.HttpContext.RequestAborted);
To get a token that cancels when either host or request is being cancelled.
Upvotes: 39
Reputation: 18387
Without using Durable Functions, I don't think it's possible. Here's a sample using Durable:
[FunctionName("ApprovalWorkflow")]
public static async Task Run(
[OrchestrationTrigger] IDurableOrchestrationContext context)
{
await context.CallActivityAsync("RequestApproval", null);
using (var timeoutCts = new CancellationTokenSource())
{
DateTime dueTime = context.CurrentUtcDateTime.AddHours(72);
Task durableTimeout = context.CreateTimer(dueTime, timeoutCts.Token);
Task<bool> approvalEvent = context.WaitForExternalEvent<bool>("ApprovalEvent");
if (approvalEvent == await Task.WhenAny(approvalEvent, durableTimeout))
{
timeoutCts.Cancel();
await context.CallActivityAsync("ProcessApproval", approvalEvent.Result);
}
else
{
await context.CallActivityAsync("Escalate", null);
}
}
}
Upvotes: 1