Pierre Jeannet
Pierre Jeannet

Reputation: 265

Detect timeout on azure function to reroute message to app service plan

I've got an Azure function unziping archives on a consumption plan. Some of them happens to take more than 10min to unzip and can timeout. I'm thinking of having a separate app service plan where I would reroute the extraction when timing out on consumption plan.

How would you do that? a timer in the function? a catch timeout exception? Do you have a better suggestion?

Thanks

Upvotes: 9

Views: 2745

Answers (2)

Norbert Huurnink
Norbert Huurnink

Reputation: 1316

The accepted answer requires ExtractArchiveAsync() to throw the OperationCanceledException. While this can work, I had a different usecase that might be useful to others finding this thread:

private static async Task ExecuteWithTimeout(Func<Task> action, int timeout)
{
      Task task = action();
      if (await Task.WhenAny(task, Task.Delay(timeout)) == task)
      {
          await task;
      }
      else
      {
          throw new TimeoutException("Timeout after " + timeout + " milliseconds");
      }
}

Upvotes: 0

Pierre Jeannet
Pierre Jeannet

Reputation: 265

For those interested I ended adding my own timeout (few seconds earlier than Azure one) to the extract function, then rerouting to another queue handled by a service app plan than don't timeout.

Code :

using (var timeoutCts = new CancellationTokenSource())
{
    try
    {
        // task completed within timeout
        timeoutCts.CancelAfter(590000);
        var counter = await ExtractArchiveAsync(archiveFullName, myBlob, timeoutCts.Token);
        log.Info($"Extracted : { counter.GetCurrentCount() }");
    }
    catch (OperationCanceledException)
    {
        // timeout logic
        log.Info($"Function timedout, redirected to long queue");
        var queue = StorageService.GetCloudQueueReference("ArchiveToExtractQueueTimedOut");
        await queue.AddMessageAsync(new CloudQueueMessage(archiveFullName));
    }
}

Upvotes: 7

Related Questions