azure-functions-durable-extension: Synchronous deserialization of request content in HandleStartOrchestratorRequestAsync results in InvalidOperationException.

Description

Calling the Durable Functions HTTP API to start an orchestration when running in a 3.0-preview (3.0.1740) Azure Functions Host results in an InvalidOperationException from Kestrel due to changes in .NET Core 3.0 regarding synchronous operations:

{
    "Message": "Something went wrong while processing your request",
    "ExceptionMessage": "Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead.",
    "ExceptionType": "System.InvalidOperationException",
    "StackTrace": "   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpRequestStream.Read(Byte[] buffer, Int32 offset, Int32 count)\n   at System.Net.Http.DelegatingStream.Read(Byte[] buffer, Int32 offset, Int32 count)\n   at System.IO.StreamReader.ReadBuffer(Span`1 userBuffer, Boolean& readToUserBuffer)\n   at System.IO.StreamReader.ReadSpan(Span`1 buffer)\n   at System.IO.StreamReader.Read(Char[] buffer, Int32 index, Int32 count)\n   at Newtonsoft.Json.JsonTextReader.ReadData(Boolean append, Int32 charsRequired)\n   at Newtonsoft.Json.JsonTextReader.ParseValue()\n   at Newtonsoft.Json.JsonReader.ReadAndMoveToContent()\n   at Newtonsoft.Json.JsonReader.ReadForType(JsonContract contract, Boolean hasConverter)\n   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)\n   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)\n   at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)\n   at Newtonsoft.Json.JsonSerializer.Deserialize[T](JsonReader reader)\n   at Microsoft.Azure.WebJobs.Extensions.DurableTask.HttpApiHandler.HandleStartOrchestratorRequestAsync(HttpRequestMessage request, String functionName, String instanceId) in d:\\a\\r1\\a\\azure-functions-durable-extension\\src\\WebJobs.Extensions.DurableTask\\HttpApiHandler.cs:line 590\n   at Microsoft.Azure.WebJobs.Extensions.DurableTask.HttpApiHandler.HandleRequestAsync(HttpRequestMessage request) in d:\\a\\r1\\a\\azure-functions-durable-extension\\src\\WebJobs.Extensions.DurableTask\\HttpApiHandler.cs:line 200"
}

The synchronous read appears to be here.

See the Azure Functions Host issue regarding this breaking change in .NET Core 3.0.

Expected behavior

The read of the JSON request body should be async so that Kestrel’s happy.

Actual behavior

The unhandled exception results in a 500 being returned from the HTTP API, as described above.

Known workarounds

Presumably setting AllowSynchronousIO to true in appsettings.json should work around the issue (at the cost to throughput), but I haven’t been able to get that to work in the context of Azure Functions.

App Details

  • Durable Functions extension version (e.g. v1.8.3): 2.0.0
  • Azure Functions runtime version (1.0 or 2.0): 3.0.1740
  • Programming language used: Rust 😄

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 20 (4 by maintainers)

Commits related to this issue

Most upvoted comments

I tried adding FUNCTIONS_V2_COMPATIBILITY_MODE set to true, but still getting that same exact error… Just like @Rutix by following the mircrosoft learn durable functions…

Could you try the following? It worked for me. Add 2 new Application setting as : Name : FUNCTIONS_V2_COMPATIBILITY_MODE Value : true Name : AllowSynchronousIO Value : true Restart the app.

I have the same issue with nodes.

@ConnorMcMahon I ran into this while following Microsoft Learn durable functions right now. This is with the sandbox and making everything from scratch. Where I think it then uses v3. Is it still an issue there?

Thanks for reporting! We’ll take a look.

BTW, very cool to see Durable Functions on rust!! 😃