Ошибка восстановления актора сохраняемости Akka.net из-за изменения сообщения с новыми свойствами

Используемый субъект сохраняемости для сохранения сообщения в базе данных SQL Server. Исходный формат сообщения показан ниже. Система запускалась с этим форматом несколько раз, и многие из этих сообщений сохранялись. В настоящее время я изменил формат сообщения, чтобы включить несколько атрибутов, как показано ниже. Может кто-нибудь дать мне представление, как это решить?

Проблема, с которой я сталкиваюсь в настоящее время, заключается в том, что при восстановлении исходного сообщения о сохранении с новыми изменениями оно не удалось и выдало ошибки, как показано ниже.

«Сбой сохранения при воспроизведении событий для persistenceId [tz-persistent-factory]. Последний известный порядковый номер [0]”

public class PlacedMissionDataCommand : IEntityActorMessage
{
    public PlacedMissionDataCommand(int trafficzoneId, int missionId, DateTime finishedTime)
    {
        TrafficzoneId = trafficzoneId;
        MissionId = missionId;
        FinishedTime = finishedTime;
        TaskGroupId = taskGroupId;
        TaskGroupActivated = taskGroupActivated;
        TaskGroupCreated = taskGroupCreated;
        TestData = testData;
    }

    public int TrafficzoneId { get; }
    public int MissionId { get; private set; }
    public DateTime FinishedTime { get; }

    public string EntityId => TrafficzoneId.ToString();
}

После внесения изменений, чтобы включить несколько свойств

public class PlacedMissionDataCommand : IEntityActorMessage
{
    public PlacedMissionDataCommand(int trafficzoneId, int missionId, DateTime finishedTime, int taskGroupId, DateTime? taskGroupActivated, DateTime? taskGroupCreated)
    {
        TrafficzoneId = trafficzoneId;
        MissionId = missionId;
        FinishedTime = finishedTime;
        TaskGroupId = taskGroupId;
        TaskGroupActivated = taskGroupActivated;
        TaskGroupCreated = taskGroupCreated;
    }

    public int TrafficzoneId { get; }
    public int MissionId { get; private set; }
    public DateTime FinishedTime { get; }

    public int TaskGroupId { get; }

    public DateTime? TaskGroupActivated { get; }

    public DateTime? TaskGroupCreated { get; }

    public string EntityId => TrafficzoneId.ToString();
}

person Amal Shalika    schedule 26.04.2017    source источник


Ответы (1)


В этом нет ничего неожиданного. Вы решили изменить контракт (схему событий) на тот, который не имеет обратной совместимости — с точки зрения сериализации — с уже сохраненными событиями. Это не конкретная проблема Akka, а более широкая проблема, связанная с отсутствием какой-либо стратегии управления версиями событий.

Некоторое время назад я написал сообщение, описывающее, как применять даже управление версиями в Akka.NET для обратно несовместимых схем — и почему вы не должны использовать сериализатор по умолчанию.

Если вам нужна более подробная лекция о проблеме, Грег Янг также написал книгу о управлении версиями событий в системах с источниками событий.

person Bartosz Sypytkowski    schedule 27.04.2017
comment
Возможно, пункт для списка дел Akka.NET: если вы не должны использовать сериализатор по умолчанию, то он не должен быть по умолчанию :-) - person mwardm; 28.04.2017
comment
К сожалению, здесь есть 2 проблемы ;) 1. Не существует такой вещи, как хороший сериализатор по умолчанию, когда дело доходит до хранения вечных данных. 2) Есть люди, которые уже используют Akka.Persistence на продакшене - я думаю, они не будут счастливы, когда после обновления библиотеки до более высокой версии они больше не смогут читать свои данные. - person Bartosz Sypytkowski; 28.04.2017
comment
@ Horusiath, что означает допуск версии при проводной сериализации? Как включить его в hocon config. Решает ли он эти проблемы? github.com/akkadotnet/Hyperion#version-tolerance - person Amal Shalika; 02.05.2017
comment
Толерантность к версии Hyperion довольно ограничена, независимо от используемой опции. Он был создан в основном для удаленного общения (короткоживущие, контекстно-зависимые данные). Если вы хотите что-то лучшее и все же довольно простое, вы можете использовать собственный сериализатор JSON - недостатки - это размер полезной нагрузки и отсутствие поддержки, если вы попытаетесь изменить имена полей. Другим вариантом является использование сериализаторов на основе схемы (таких как protobuf или MS Bond), где поля запоминаются как смещения, поэтому их имена могут меняться, но им нужны специальные атрибуты или файлы схемы для информирования о смещении для каждого поля. - person Bartosz Sypytkowski; 02.05.2017