Azure / azure-functions-durable-extension

Durable Task Framework extension for Azure Functions
MIT License
713 stars 270 forks source link

SubOrchestration with unserialized return type will cause function app to hang until timeout. #2431

Closed ShakeySnake closed 1 year ago

ShakeySnake commented 1 year ago

Description

I had a sub-orchestration that had a return type of a custom enum, defined in a namespace. When the orchestration reached the call for this sub-orchestration, the function will hang until it times out. I believe this behavior is caused if an unserializable type is used as a return value for the suborchestration call.

NOTE: JavaScript issues should be reported here: https://github.com/Azure/azure-functions-durable-js

Expected behavior

If an unsupported type is used in Suborchestration calls, it should be: Caught in analyzers. Throw an exception in runtime.

Actual behavior

Build completes without issues. Function app will hang until timeout.

Relevant source code snippets

[FunctionName("Orchestration_CreateICMSAndUpdateTriage")]
public static async Task<ICMCreation[]> CreateICMsAndUpdateTriage([OrchestrationTrigger] IDurableOrchestrationContext context, ILogger log)
{
      ...
   // Rerun Autopipe Processing.
   var dataFactoryPipeline = context.CallActivityAsync("Function_GetSetting", "DataFactory_DataFactoryName");
   DataFactoryStatus = await context.CallSubOrchestratorWithRetryAsync<DataFactoryStatus>("Orchestration_UpdateDataStores", Utilities.GetRetryOptions(), dataFactoryPipeline)

     ...

}

[FunctionName("Orchestration_UpdateDataStores")]
public static async Task<DataFactoryStatus> RunDataStorePipeline([OrchestrationTrigger] IDurableOrchestrationContext context, ILogger logger)
{
   var pipelinenName = context.GetInput<string>();
   string runId = await context.CallActivityWithRetryAsync<string>("Function_StartDataFactoryPipeline", Utilities.GetRetryOptions(), pipelinenName);
   DataFactoryStatus pipelineResult = await context.CallActivityWithRetryAsync<DataFactoryStatus>("Function_CheckAndWaitForPipelineRun", Utilities.GetRetryOptions(), runId);

   ...

   return pipelineResult;
}

Known workarounds

Changing the return type of RunDataStorePipeline from the enum DataFactoryStatus to a string fixed the issue.

App Details

Screenshots

This snapshot will show where "Function_GetSetting" was called and completed, but "Orchestration_UpdateDataStores" never starts until the timeout is reached 30 minutes later. image

If deployed to Azure

We have access to a lot of telemetry that can help with investigations. Please provide as much of the following information as you can to help us investigate!

If you don't want to share your Function App or storage account name GitHub, please at least share the orchestration instance ID. Otherwise it's extremely difficult to look up information.

ShakeySnake commented 1 year ago

This was a problem with my code. Missing an await in this line.

var dataFactoryPipeline = context.CallActivityAsync("Function_GetSetting", "DataFactory_DataFactoryName");