Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DateOnly is not correctly handled by activity function #2009

Closed
mdddev opened this issue Nov 12, 2021 · 2 comments
Closed

DateOnly is not correctly handled by activity function #2009

mdddev opened this issue Nov 12, 2021 · 2 comments
Labels
Needs: Author Feedback Waiting for the author of the issue to respond to a question no-recent-activity

Comments

@mdddev
Copy link

mdddev commented Nov 12, 2021

Description

NET6 introduced a DateOnly type. Passing it as input to an activity function or returning it from it is not correctly handled.

Expected behavior

The DateOnly input to and output from an activity function should be recognised correctly.

Actual behavior

DateOnly.MinValue is used.

Relevant source code snippets

CSPROJ

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <AzureFunctionsVersion>v4</AzureFunctionsVersion>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.Azure.WebJobs.Extensions.DurableTask" Version="2.5.1" />
    <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.0.1" />
  </ItemGroup>
  <ItemGroup>
    <None Update="host.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="local.settings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
    </None>
  </ItemGroup>
</Project>

REPRO

using System;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;

namespace azfnet6dur
{
    public static class dateonlytest
    {
        [FunctionName(nameof(dateonlytest.Orchestrator))]
        public static async Task Orchestrator([OrchestrationTrigger] IDurableOrchestrationContext context, ILogger log)
        {
            var dateOnly = new DateOnly(2021, 11, 12);
            
            if (!context.IsReplaying)
            {
                log.LogWarning($"Passing DateOnly as input to activity function= {dateOnly.ToString()}");
            }

            var result = await context.CallActivityAsync<DateOnly>(nameof(dateonlytest.Activity), dateOnly);

            log.LogWarning($"Received DateOnly return value from activity function= {result.ToString()}");

            if (dateOnly != result)
            {
                var msg = $"{nameof(DateOnly)} type could not be handled correctly by Durable Functions. EXPECTED= {dateOnly.ToString()}";
                throw new ArgumentOutOfRangeException(nameof(result), result, msg);
            }
        }

        [FunctionName(nameof(dateonlytest.Activity))]
        public static DateOnly Activity([ActivityTrigger] IDurableActivityContext ctx, ILogger log)
        {
            var input = ctx.GetInput<DateOnly>();
            log.LogWarning($"Received DateOnly as input from, and returning it to orchestrator function= {input.ToString()}");
            return input;
        }


        [FunctionName(nameof(dateonlytest.Trigger))]
        public static async Task Trigger([HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequestMessage req,
        [DurableClient] IDurableOrchestrationClient starter)
        {
            await starter.StartNewAsync(nameof(dateonlytest.Orchestrator), null);
        }
    }
}

DEMO

[2021-11-12T11:13:53.973Z] Host lock lease acquired by instance ID '00000000000000000000000041CA841C'.
[2021-11-12T11:13:56.445Z] Executing 'Trigger' (Reason='This function was programmatically called via the host APIs.', Id=56c57e52-be39-4487-b2ae-8924e7f6159f)
[2021-11-12T11:13:56.588Z] Executed 'Trigger' (Succeeded, Id=56c57e52-be39-4487-b2ae-8924e7f6159f, Duration=167ms)
[2021-11-12T11:13:56.677Z] Executing 'Orchestrator' (Reason='(null)', Id=bc10198b-fbb8-4149-aea5-3dd9814b326b)
[2021-11-12T11:13:56.693Z] Passing DateOnly as input to activity function= 12.11.2021
[2021-11-12T11:13:56.709Z] Executed 'Orchestrator' (Succeeded, Id=bc10198b-fbb8-4149-aea5-3dd9814b326b, Duration=34ms)
[2021-11-12T11:13:56.768Z] Executing 'Activity' (Reason='(null)', Id=027c4d97-7fc6-49ba-948a-6cf9d74ca8bc)
[2021-11-12T11:13:56.773Z] Received DateOnly as input from, and returning it to orchestrator function= 01.01.0001
[2021-11-12T11:13:56.776Z] Executed 'Activity' (Succeeded, Id=027c4d97-7fc6-49ba-948a-6cf9d74ca8bc, Duration=11ms)
[2021-11-12T11:13:56.906Z] Executing 'Orchestrator' (Reason='(null)', Id=a4cfe26c-195e-4176-8926-aadaae511bd4)
[2021-11-12T11:13:56.910Z] Received DateOnly return value from activity function= 01.01.0001
[2021-11-12T11:13:56.928Z] c1c922e95fab4a44901a93f00f84f5aa: Function 'Orchestrator (Orchestrator)' failed with an error. Reason: System.ArgumentOutOfRangeException: DateOnly type could not be handled correctly by Durable Functions. EXPECTED= 12.11.2021 (Parameter 'result')
[2021-11-12T11:13:56.930Z] Actual value was 01.01.0001.
[2021-11-12T11:13:56.931Z]    at azfnet6dur.dateonlytest.Orchestrator(IDurableOrchestrationContext context, ILogger log) in C:\Users\me\source\azfnet6dur\dateonlytest.cs:line 30
[2021-11-12T11:13:56.932Z]    at Microsoft.Azure.WebJobs.Host.Executors.VoidTaskMethodInvoker`2.InvokeAsync(TReflected instance, Object[] arguments) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\VoidTaskMethodInvoker.cs:line 20
[2021-11-12T11:13:56.933Z]    at Microsoft.Azure.WebJobs.Host.Executors.FunctionInvoker`2.InvokeAsync(Object instance, Object[] arguments) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionInvoker.cs:line 52
[2021-11-12T11:13:56.933Z]    at Microsoft.Azure.WebJobs.Extensions.DurableTask.TaskOrchestrationShim.InvokeUserCodeAndHandleResults(RegisteredFunctionInfo orchestratorInfo, OrchestrationContext innerContext) in D:\a\r1\a\azure-functions-durable-extension\src\WebJobs.Extensions.DurableTask\Listener\TaskOrchestrationShim.cs:line 150. IsReplay: False. State: Failed. HubName: TestHubName. AppName: . SlotName: . ExtensionVersion: 2.5.1. SequenceNumber: 8. TaskEventId: -1
[2021-11-12T11:13:56.952Z] Executed 'Orchestrator' (Failed, Id=a4cfe26c-195e-4176-8926-aadaae511bd4, Duration=43ms)
[2021-11-12T11:13:56.954Z] System.Private.CoreLib: Exception while executing function: Orchestrator. System.Private.CoreLib: Orchestrator function 'Orchestrator' failed: DateOnly type could not be handled correctly by Durable Functions. EXPECTED= 12.11.2021 (Parameter 'result')
[2021-11-12T11:13:56.955Z] Actual value was 01.01.0001.

Known workarounds

NET6 System.Text.Json Serializer does not yet support DateOnly, there is a workaround using a custom converter. Is there any way we can inject something like this into Durable Functions?

@ghost ghost added the Needs: Triage 🔍 label Nov 12, 2021
@cgillum
Copy link
Member

cgillum commented Apr 19, 2022

@AnatoliB AnatoliB added Needs: Author Feedback Waiting for the author of the issue to respond to a question and removed Needs: Triage 🔍 labels Apr 19, 2022
@ghost ghost added the no-recent-activity label Apr 24, 2022
@ghost
Copy link

ghost commented Apr 24, 2022

This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 4 days. It will be closed if no further activity occurs within 3 days of this comment.

@ghost ghost closed this as completed Apr 27, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs: Author Feedback Waiting for the author of the issue to respond to a question no-recent-activity
Projects
None yet
Development

No branches or pull requests

3 participants