0
votes

I'm using a Logic App where the workflow calls at a certain point an Azure Function using the Webhook URL (as a workaround to Azure Functions Durable).

The goal of this function is to insert/update data into an Azure SQL Database with a SQL request

 "MERGE INTO...USING...WHEN NOT MATCHED...WHEN MATCHED AND...".

In the logs of the Azure Function, i could see it failed and it seems to run 4 times (maybe due to the supposed Timeout, I don't know), but I don't understand since I increased the CommandTimeout to 50minutes and I set 1Hour to the Timeout of the action "Launch Webhook" in the LogicApp :S Here's the sample of the exception logged in the Azure Function :

Exception while executing function: XmlImport_DoWork Microsoft.Azure.WebJobs.Host.FunctionInvocationException : Exception while executing function: XmlImport_DoWork ---> System.Data.SqlClient.SqlException : Execution Timeout Expired. The timeout period elapsed prior to completion of the operation or the server is not responding. The statement has been terminated. ---> System.ComponentModel.Win32Exception : The wait operation timed out

The table actually have around 250,000 lines and it seems to be good when I launch the LogicApp (and so the Azure Function) to a table which is almost empty !

Any ideas about what's going on and how to fix it ? I tried to look at the "Query Performance Insight" in Azure SQL database component but there are nothing in "Recommendations" section

The Function App where are stored my Azure Functions is using an App Service Plan. BTW the XML file I was trying to import in DB has a size of 20M but I tried with a lighter XML (9M) but it didn't work either

1
Perhaps you could use Azure Automation instead, which does not have this limitation. Is this loading Blob > SQL Azure?Nick.McDermaid
Logic App run the Azure Function after creating a blob in a Storage Account yesmoueidat
I'm just trying to understand what the logic app actually does, and whether it is suitable to build on a different platform (Maybe Azure Data Factory or Azure Automation) which does not have the constraints of logic apps.Nick.McDermaid
I understand ;) Well the Logic App get the XML file from a SFTP Server --> Then it creates a blob in a StorageAccount --> Then it launches the Azure Function by calling its Webhook URL --> At the end of the process the latter should call the CallbackUrl to tell him the job is done --> finally it deletes the files in the StorageAccount and in the SFTP Servermoueidat
and the Azure function loads this XML file into a database? You can probably do that in Azure automation which does not have the timeout issue. I have certainly used Azure Automation to import files into a database from blob storage, and Azure automation can be triggered from a web hook. Not sure about it triggering a web hook when complete but I'm sure it's possibleNick.McDermaid

1 Answers

0
votes

Azure Durable Function: V2 and .Net Core 2.2 - Timeout expired issue RESOLOVED

The activity function 'A_ValidateAndImportData' failed: "Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.". See the function execution logs for additional details.

Using DAPPER to call SQL Server stored procedure: Dapper not honoring "Connection Timeout" Property in the connection string

Solution: Use a connection timeout parameter to provide "0"(ZERO or increase timeout according to your need) to solve this problem

Example Code:

 public async Task<int> ValidateAndImportData(string connectionString, int param1,
            int databaseTimeOut = 0)
        {
            using (var connection = new SqlConnection(connectionString))
            {
                var param = new DynamicParameters();
                param.Add("@param1", param1);
                param.Add("@returnStatus", dbType: DbType.Int32, direction: ParameterDirection.Output);

                await connection.ExecuteAsync("[dbo].[ValidateAndImportData]", param,
                    commandType: CommandType.StoredProcedure, commandTimeout: databaseTimeOut).ConfigureAwait(false);

                return param.Get<int>("returnStatus");
            }
        }