Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Azure Functions using Cancellation Token with Http Trigger

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

like image 392
Noob Coder Avatar asked Feb 13 '20 07:02

Noob Coder


2 Answers

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.

like image 175
Miq Avatar answered Oct 14 '22 12:10

Miq


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);
        }
    }
}

https://docs.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-overview?tabs=csharp#human

like image 34
Thiago Custodio Avatar answered Oct 14 '22 12:10

Thiago Custodio