Ошибка персистентности при воспроизведении событий... System.NotSupportedException: универсальный IDictionary еще не поддерживается
Можете ли вы помочь? При сохранении один или два раза работает нормально. Три или больше, и я получаю это:
[INFO][11/28/2017 2:57:27 PM][Thread 0005][[akka://ECHO3DEV/user/api-master/PortfolioCoordinator/TK#425630680]] Portfolio Actor: TK completely recovered. Current Positions: ......
11/28/2017 9:57:27 AM portfolio- Actor started...
[ERROR][11/28/2017 2:57:27 PM][Thread 0005][[akka://ECHO3DEV/user/api-master/PortfolioCoordinator/TK/TK-IBM#1280277591]] **Persistence failure when replaying events for persistenceId [portfolio-TK-IBM]. **Last known sequence number [3]
Cause: System.NotSupportedException: Generic IDictionary<TKey,TValue> are not yet supported****
at Hyperion.SerializerFactories.DictionarySerializerFactory.<>c__DisplayClass3_0.<BuildSerializer>b__0(Stream stream, DeserializerSession session)
at Hyperion.ValueSerializers.ObjectSerializer.ReadValue(Stream stream, DeserializerSession session)
at lambda_method(Closure , Stream , DeserializerSession )
at Hyperion.ValueSerializers.ObjectSerializer.ReadValue(Stream stream, DeserializerSession session)
at lambda_method(Closure , Stream , DeserializerSession )
at Hyperion.ValueSerializers.ObjectSerializer.ReadValue(Stream stream, DeserializerSession session)
at lambda_method(Closure , Stream , DeserializerSession )
at Hyperion.ValueSerializers.ObjectSerializer.ReadValue(Stream stream, DeserializerSession session)
at Hyperion.SerializerFactories.DefaultDictionarySerializerFactory.<>c__DisplayClass3_0.<BuildSerializer>b__0(Stream stream, DeserializerSession session)
at Hyperion.ValueSerializers.ObjectSerializer.ReadValue(Stream stream, DeserializerSession session)
at lambda_method(Closure , Stream , DeserializerSession )
at Hyperion.ValueSerializers.ObjectSerializer.ReadValue(Stream stream, DeserializerSession session)
at lambda_method(Closure , Stream , DeserializerSession )
at Hyperion.ValueSerializers.ObjectSerializer.ReadValue(Stream stream, DeserializerSession session)
at Hyperion.Serializer.Deserialize[T](Stream stream)
at Akka.Serialization.HyperionSerializer.FromBinary(Byte[] bytes, Type type)
at Akka.Persistence.Sql.Common.Journal.AbstractQueryExecutor.ReadEvent(DbDataReader reader)
at Akka.Persistence.Sql.Common.Journal.AbstractQueryExecutor.<SelectByPersistenceIdAsync>d__44.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Akka.Persistence.Sql.Common.Journal.SqlJournal.<ReplayMessagesAsync>d__32.MoveNext()
Как я могу отладить это?
1 ответ
Это не проблема самого Akka.Persistence. Сама ошибка заключается в сериализаторе Hyperion, который не следует использовать для сохранения (только для удаленного взаимодействия). В конце концов, данные, которые вы собираетесь хранить, принадлежат вам, и будет лучше, если вы сохраните контроль над тем, как они будут храниться для вас;)
Я описал эту и другие распространенные ошибки Akka. Персональные ошибки здесь.
Одна из причин, по которой Hyperion не используется для постоянства, заключается в том, что он все еще находится в бета-версии, а его двоичный формат НЕ установлен в камне. Это означает, что после обновления сериализатора вы больше не сможете читать события назад.
По этой причине лучше явно определить сериализатор с известной схемой для ваших событий. Вы можете выбрать свой собственный, или, например, выбрать MsqPack или Microsoft Bond - они работают с явным определением схемы, облегчая работу с течением времени и изменением содержимого событий.
Чтобы определить пользовательский сериализатор, вам нужно пометить ваши события каким-то типом (т. Е. Пустым интерфейсом), который вы будете использовать, чтобы распознать, какой сериализатор применяется к ним. Затем просто определите отображение сериализатора в конфигурации HOCON:
akka.actor {
serializers.msgpack= "Akka.Serialization.MessagePack.MsgPackSerializer, Akka.Serialization.MessagePack"
serialization-bindings {
"MyNamespace.IDomainEvent, MyAssembly" = msgpack
}
}
Здесь я использую сериализатор Akka.NET MsgPack для пользовательского интерфейса IDomainEvent
, по которому я узнаю мои события. Полные имена типов со сборкой необходимы для распознавания типов.