By default, all snapshots are stored as files directly in ./snapshots
directory of the application, while events are stored in the memory. Because of that you should consider using a one of the akka.persistence plugins for the production purposes.
Your problem happens because you're using akka.net default serializers (dedicated for networking) which are not very version tolerant - so changing any fields, their types, class names or namespaces makes previous version of the class non-deserializable - and in future will be subject to change. This is also why it's strongly discouraged to use default serializers for persistence.
How to make a custom Akka.NET Serializer
While there are plans to improve serializers API, at the current moment (Akka.NET v1.3.9), to make your own serializer you need to simply inherit from Akka.Serialization.Serializer
class:
public sealed class MySerializer : Serializer
{
public MySerializer(ExtendedActorSystem system) : base(system) { }
public override int Identifier => /* globaly unique serializer id */;
public override bool IncludeManifest => true;
public override byte[] ToBinary(object obj)
{
// serialize object
}
public override object FromBinary(byte[] bytes, Type type)
{
// deserialize object
}
}
Keep in mind that Identifier
property must be unique in cluster scope - usually values below 100 are used by akka.net internal serializers, therefore it's better to use higher values.
How to bind serializer to be used for a given type
By convention Akka.NET uses empty interfaces to mark message types that are supposed to be serialized. Then you can setup your HOCON configuration to use a specific serializer for a given interface:
akka.actor {
serializers {
my-serializer = ""MyNamespace.MySerializer, MyAssembly""
}
serialization-bindings {
""MyNamespace.MyInterface, MyAssembly"" = my-serializer
}
}
Where MyInterface
is interface assigned to a message type you want to serialize/deserialize with MySerializer
.