HowTo — LogicApp calling an azure function with can potentially respond in more than 2 minutes
I have a scenario where a lot of data processing happening in Azure Function and it can more than 2 minutes to execute on a busy day. Standard HTTP action has 2 minutes of timeout which failed during load testing ( yes even in azure PaaS services we have limitations and timeouts).
How to solve this problem, well there are three approaches we have ( at least I can think of).
Approach1: Redesign AzureFunciton processing to limit the scope of data processing so that it always returns within 2 minutes timeout. It is not feasible in my scenario to redesign AzureFunciton, thus not considered for solution
Approach2: Convert AzureFunction in durable AzureFunction. This is like a gold standard solution and should be in place for AzureFunction but it is not there and practically not feasible to change AzureFunction due to cost and impact on other interfaces. Thus not considered for solution primarily due to factors beyond technology ( it not always the best technical approach is the automatic choice for solution)
Approach 3: At logic app instead of HTTP action use HTTP webhook. Along with this small change in AzureFunction calling part to respond to the webhook asynchronously
LogicApp changes: Use the same details as used in HTTP call for function app only add callback URL as an additional field in the request body.

Storage Account changes: Add a storage queue (processDataQueue), I have used the same storage account as used by FunctionApp
Azure Function Changes: We will store incoming messages to a storage queue and then trigger the actual function by message in the storage queue which has a callback URL as an additional field.
[FunctionName(“GetData”)]
public static IActionResult GetDataAsync(
[HttpTrigger(AuthorizationLevel.Anonymous, “post”)] HttpRequest req,
ILogger log,
[Queue(“processDataQueue”)] out JSONData process)
{
log.LogInformation(“Webhook Logic Apps “);
string requestBody = new StreamReader(req.Body).ReadToEnd();
process = new JSONData { data = requestBody };
return new AcceptedResult();
}
public static HttpClient client = new HttpClient();
/// <summary>
/// Queue trigger function to pick data and process
/// </summary>
[FunctionName(“QueueTriggerprocessDataQueue”)]
public static async Task RunAsync([QueueTrigger(“processDataQueue”)] JSONData item, ILogger log)
{
Data objData = new Data();
//Function Processing
HttpResponseMessage objHttpResponseMessage = await objData.RunAsync(item.data, log);
var content = objHttpResponseMessage.Content;
string responseBody = await content.ReadAsStringAsync();
var responseJson = JsonConvert.SerializeObject(responseBody);
using var httpContent = new StringContent(responseJson, Encoding.UTF8, “application/json”);
dynamic data = JsonConvert.DeserializeObject(item.data);
string callbackUrl = data?.callbackUrl;
var response = await client.PostAsync(callbackUrl, httpContent);
response.EnsureSuccessStatusCode();
}
public class JSONData
{
public string data { get; set; }
}
Keep sharing…