Azure / azure-functions-durable-extension

Durable Task Framework extension for Azure Functions
MIT License
711 stars 263 forks source link

Different serialization format for class based entities cause trouble in .NET 8 isolated #2714

Open thomaseyde opened 5 months ago

thomaseyde commented 5 months ago

Problem

Function based entities save state in a "wrapper" property named after the state type.

This makes it very hard to switch between function types as there are no serialization hooks available. It is too late to change the implementation, I guess. The next best thing would be to have a deserialization hook like the InitializeState method.

A type:

record Answer(int Value);

is saved as (the state value is actually a json string, but that was too hard to type):

{ "state": { "Answer": {"Value": 42} } }

Class based entities derived from TaskEntity<T> save properties directly on the state:

{ "state": {"Value": 42} }

Workaround

My workaround works, but it is too much boiler plate and no way to control when to run it or not.

public static async Task Dispatch([EntityTrigger] TaskEntityDispatcher dispatcher)
{
    await dispatcher.DispatchAsync(
        operation =>
        {
            MigrateFromFunction(operation.State);
            return default;
        });
    await dispatcher.DispatchAsync<MyFunction>();
}

static void MigrateFromFunction(TaskEntityState state)
{
    if (!state.HasState) return;

    MyState? myState;
    try
    {
        myState = state.GetState<MyState>();
    }
    catch (JsonException)
    {
        myState = null;
    }

    if (myState == null) return;

    var json = JsonSerializer.Serialize(myState);
    state.SetState(json);
}