microsoft / durabletask-mssql

Microsoft SQL storage provider for Durable Functions and the Durable Task Framework
MIT License
87 stars 32 forks source link

Durable Entity creates NullReferenceException with Microsoft.Azure.Functions.Worker.Extensions.DurableTask.SqlServer #205

Open Enlatic opened 10 months ago

Enlatic commented 10 months ago

Hi.

I have slight problem. Dont know if it a configuration issue on my side or something else.

Currently migrating our software from ..NET6 -> .NET8 and from InProc to Isolated. All good works as intended. The Null Reference Exception shows its self when I switch from AzureStorage to SQL Server.

A bit of code to exemplify the issue.

[Function(nameof(ProcessData))]
 public async Task RunOrchestrator(
     [OrchestrationTrigger] TaskOrchestrationContext context)
 {
     ILogger logger = context.CreateReplaySafeLogger(nameof(ProcessData));
     var input = context.GetInput<string>();

     var result = await context.CallActivityAsync<RegionMix>("ActProcessData", input);

     var countryKey = string.IsNullOrEmpty(result.CountryCode) ? result.Country : result.CountryCode;
     await context.Entities.SignalEntityAsync(new EntityInstanceId(nameof(Entities.EnergyMix), countryKey), "Add", result);

 }

var result is a POCO. Running this code, I get the NullReferenceException on SignalEntify.

My config is: Microsoft.Azure.Functions.Worker - 1.20.1 Microsoft.Azure.Functions.Worker.Extensions.DurableTask - 1.1.0 Microsoft.Azure.Functions.Worker.Extensions.DurableTask.SqlServer - 1.2.2 Microsoft.Azure.Functions.Worker.Sdk - 1.16.4

host.json :)

{
  "version": "2.0",
  "extensions": {
    "http": {
      "routePrefix": ""
    },
    "durableTask": {
      "hubName": "%TaskHubConfig%",
      "storageProvider": {
        "type": "mssql",
        "connectionStringName": "Durable_SQLDB_Connection",
        "createDatabaseIfNotExists": true
      }
    }
  },
  "logging": {
    "applicationInsights": {
      "samplingSettings": {
        "isEnabled": true,
        "excludedTypes": "Request"
      },
      "enableLiveMetricsFilters": true
    },
    "logLevel": {
      "default": "Information",
      "DurableTask.SqlServer": "Debug",
      "DurableTask.Core": "Debug"
    }
  }
}

After a bit of debugging. The exception originates OrchestrationEntityContext class on DurableTask.Core

 internal void AdjustOutgoingMessage(string instanceId, RequestMessage requestMessage, DateTime? cappedTime, out string eventName)
 {
     if (cappedTime.HasValue)
     {
         eventName = EntityMessageEventNames.ScheduledRequestMessageEventName(cappedTime.Value);
     }
     else
     {
         this.messageSorter.LabelOutgoingMessage(
             requestMessage,
             instanceId,
             this.innerContext.CurrentUtcDateTime,
             this.innerContext.EntityParameters.EntityMessageReorderWindow);

         eventName = EntityMessageEventNames.RequestMessageEventName;
     }
 }

The this.innerContext.EntityParameters is not populated and is NULL.

Is this intentionally? If yes, how do I fix it...

//Daniel

oleks9o6 commented 9 months ago

It looks like it is rather due to changing the storage to MSSQL than .NET migration. I faced the same issue https://github.com/microsoft/durabletask-dotnet/issues/246, and it seems that MSSQL storage might not support durable entities yet.

cgillum commented 9 months ago

Durable Entities should be supported on the MSSQL backend. There are tests for the feature here.

However, our tests only target the in-proc implementation of entities. It's possible that there's a problem when using Durable Entities on MSSQL with the .NET Isolated worker, which has a different internal implementation. Will need to try and set up a local repro to see what's going on.

oleks9o6 commented 9 months ago

Durable Entities should be supported on the MSSQL backend. There are tests for the feature here.

However, our tests only target the in-proc implementation of entities. It's possible that there's a problem when using Durable Entities on MSSQL with the .NET Isolated worker, which has a different internal implementation. Will need to try and set up a local repro to see what's going on.

Thanks for confirming it should work. I provided a minimal repro example in the linked issue here https://github.com/microsoft/durabletask-dotnet/issues/246. Let me know if you need any additional details.

cgillum commented 9 months ago

Thanks, so based on the issue you linked to, it looks like new feature work is required to support entities in the .NET Isolated worker. I was able to reproduce the issue using the minimal repro you provided (thanks!) so I can use that as a starting point for ensuring that .NET Isolated entities work correctly.

cgillum commented 9 months ago

The following PR in DTFx core should replace the null-ref exception with a friendlier exception: https://github.com/Azure/durabletask/pull/1047.