Search code examples
c#asynchronoustaskazure-functions

How can I return before a task completes but keep it running?


I have an Azure Function in which an asynchronous method async Task<IActionResult> MethodA calls async Task MethodB. Since MethodB is expected to always take longer than 1 minute, we are required to start MethodB and return 202 Accepted in MethodA before MethodB finishes. Inside MethodB, we keep track of the status by storing the information in a table. If MethodB fails or throws an exception, we catch the exception an update the table accordingly. This way, when the client queries the status of the task, it fetches the result from the table. Here is the pseudo-code of what actually happens:

// The starting method.
[FunctionName("MethodA")]
public static async Task<IActionResult> MethodA(
    [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "start")] HttpRequest request,
    ILogger logger)
{
    // Somehow start MethodB so that it runs and we can return 202 Accepted before it finishes.
    return new AcceptedResult();
}

private static async Task MethodB(ILogger logger)
{
    try
    {
        // Insert row into table with status "running" and do logging.
        // Do stuff that takes longer than 1 minute and do more logging.
    }
    catch(Exception exception) // Very general exception handling for pseudo-code.
    {
        // Update row in table to status "failed" an do some logging.
    }
}

[FunctionName("MethodC")
public static async Task<IActionResult> MethodC(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "get")] HttpRequest request,
    ILogger logger)
{
    // Looks for row in table, gets the status, and do logging.
    // Returns 200 Ok if still running or succeeded, otherwise otherwise some failure code.
    // Also returns the exact status in the table to differentiate between running and succeeded.
}

What are some options to start MethodB so that it still runs after I return 202 Accepted? I saw many things about different solutions, some of which block threads and some don't, so it's all a bit very confusing to me, as I am new to this.


Solution

  • Azure functions support durable functions. One use case for this as described in the docs is the async HTTP API pattern to start a long running task, return early and support checking on the status from the client later. Depending on the details of your methods A and B you may also want to use this for chaining but it sounds like really you can use a durable function and get rid of A and C altogether because you are trying to implement what they already support.