Ошибка персистентности при воспроизведении событий... 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, по которому я узнаю мои события. Полные имена типов со сборкой необходимы для распознавания типов.

Другие вопросы по тегам