2

Used persistence actor to persist message into SQL Server database. Initial message format is as in below. System run with this format few times and many of those messages were persisted. Currently I changed message format to include few attributes as in below. Can someone give me an idea how to solve this?

Problem currently I am facing is when recovering initial persist message with new changes it failed and giving errors like below.

“Persistence failure when replaying events for persistenceId [tz-persistent-factory]. Last known sequence number [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();
}

After changes done to include few properties

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();
}
Amal Shalika
  • 1,077
  • 1
  • 13
  • 22

1 Answers1

4

This is nothing unexpected. You've decided to change the contract (event schema) to the one that has no backwards compatibility - in terms of serialization - with events that have been already stored. This is not an Akka specific problem, but more broad issue with not having any event versioning strategy.

I've written a post some time ago describing how to apply even versioning in Akka.NET for backwards incompatible schemas - and why you shouldn't use default serializer.

If you need more complete lecture about the problem, Greg Young also wrote a book about event versioning in event sourced systems.

Bartosz Sypytkowski
  • 7,463
  • 19
  • 36
  • Maybe an item for the Akka.NET to-do list: If you shouldn't use the default serializer, then it shouldn't be the default :-) – mwardm Apr 28 '17 at 13:53
  • 1
    Unfortunately there are 2 problems here ;) 1. There is no such thing as good default serializer when it comes to storing everlasting data. 2) There are people already using Akka.Persistence on production - I guess they won't be happy, when after updating library to higher version, they won't be able to read their data any longer. – Bartosz Sypytkowski Apr 28 '17 at 18:08
  • @Horusiath what does mean by version tolerance by wire serialize?. How to enable it on hocon config. Does it resolve this issues? https://github.com/akkadotnet/Hyperion#version-tolerance – Amal Shalika May 02 '17 at 06:06
  • 1
    Hyperion version tolerance is pretty limited, regardless of option used. It was build mostly for remote communication (short living, context-dependent data). If you want something better and still quite simple, you may use custom JSON serializer - disadvantages are size of a payload and no support if you'll try to change field names. Other option is to use schema-based serializers (like protobuf or MS Bond), where fields are remembered as offsets, so their names can change, but they need special attributes or schema files to inform about the offset for each field. – Bartosz Sypytkowski May 02 '17 at 06:57