AqlaSolutions / AqlaSerializer

Binary serializer with full .NET support!
http://www.aqla.net
Other
17 stars 3 forks source link

A deferred key does not have a value yet (NoteObject call missed?) #31

Closed inethui closed 2 years ago

inethui commented 2 years ago

I got the following exception when trying to deserialize an object, any idea what's wrong?

AqlaSerializer.ProtoException
  HResult=0x80131500
  Message=A deferred key does not have a value yet (NoteObject call missed?)
  Source=aqlaserializer
  StackTrace:
   at AqlaSerializer.NetObjectCache.GetKeyedObject(Int32 key, Boolean allowMissing) in D:\AqlaSerializer-v.2.0.1.1031\src\protobuf-net\NetObjectCache.cs:line 49
   at AqlaSerializer.NetObjectHelpers.ReadNetObject_End(Object value, ReadReturnValue r, ProtoReader source, Object oldValue, Type type, NetObjectOptions options) in D:\AqlaSerializer-v.2.0.1.1031\src\protobuf-net\NetObjectHelpers.Read.cs:line 37
   at AqlaSerializer.Serializers.CompiledSerializer.AqlaSerializer.Serializers.IProtoSerializer.Read(Object value, ProtoReader source) in D:\AqlaSerializer-v.2.0.1.1031\src\protobuf-net\Serializers\CompiledSerializer.cs:line 74
   at AqlaSerializer.Meta.RuntimeTypeModel.Deserialize(Int32 key, Object value, ProtoReader source, Boolean isRoot) in D:\AqlaSerializer-v.2.0.1.1031\src\protobuf-net\Meta\RuntimeTypeModel.cs:line 1080
   at AqlaSerializer.ProtoReader.ReadTypedObject(Object value, Int32 key, ProtoReader reader, Type type) in D:\AqlaSerializer-v.2.0.1.1031\src\protobuf-net\ProtoReader.cs:line 787
   at AqlaSerializer.ProtoReader.ReadObject(Object value, Int32 key, ProtoReader reader) in D:\AqlaSerializer-v.2.0.1.1031\src\protobuf-net\ProtoReader.cs:line 773
   at AqlaSerializer.Serializers.CompiledSerializer.AqlaSerializer.Serializers.IProtoSerializer.Read(Object value, ProtoReader source) in D:\AqlaSerializer-v.2.0.1.1031\src\protobuf-net\Serializers\CompiledSerializer.cs:line 74
   at AqlaSerializer.Meta.RuntimeTypeModel.Deserialize(Int32 key, Object value, ProtoReader source, Boolean isRoot) in D:\AqlaSerializer-v.2.0.1.1031\src\protobuf-net\Meta\RuntimeTypeModel.cs:line 1080
   at AqlaSerializer.ProtoReader.ReadTypedObject(Object value, Int32 key, ProtoReader reader, Type type) in D:\AqlaSerializer-v.2.0.1.1031\src\protobuf-net\ProtoReader.cs:line 787
   at AqlaSerializer.ProtoReader.ReadObject(Object value, Int32 key, ProtoReader reader) in D:\AqlaSerializer-v.2.0.1.1031\src\protobuf-net\ProtoReader.cs:line 773
   at AqlaSerializer.Serializers.CompiledSerializer.AqlaSerializer.Serializers.IProtoSerializer.Read(Object value, ProtoReader source) in D:\AqlaSerializer-v.2.0.1.1031\src\protobuf-net\Serializers\CompiledSerializer.cs:line 74
   at AqlaSerializer.Meta.RuntimeTypeModel.Deserialize(Int32 key, Object value, ProtoReader source, Boolean isRoot) in D:\AqlaSerializer-v.2.0.1.1031\src\protobuf-net\Meta\RuntimeTypeModel.cs:line 1080
   at AqlaSerializer.ProtoReader.ReadTypedObject(Object value, Int32 key, ProtoReader reader, Type type) in D:\AqlaSerializer-v.2.0.1.1031\src\protobuf-net\ProtoReader.cs:line 787
   at AqlaSerializer.ProtoReader.ReadObject(Object value, Int32 key, ProtoReader reader) in D:\AqlaSerializer-v.2.0.1.1031\src\protobuf-net\ProtoReader.cs:line 773
   at AqlaSerializer.Serializers.CompiledSerializer.AqlaSerializer.Serializers.IProtoSerializer.Read(Object value, ProtoReader source) in D:\AqlaSerializer-v.2.0.1.1031\src\protobuf-net\Serializers\CompiledSerializer.cs:line 74
   at AqlaSerializer.Meta.RuntimeTypeModel.Deserialize(Int32 key, Object value, ProtoReader source, Boolean isRoot) in D:\AqlaSerializer-v.2.0.1.1031\src\protobuf-net\Meta\RuntimeTypeModel.cs:line 1080
   at AqlaSerializer.ProtoReader.ReadTypedObject(Object value, Int32 key, ProtoReader reader, Type type) in D:\AqlaSerializer-v.2.0.1.1031\src\protobuf-net\ProtoReader.cs:line 787
   at AqlaSerializer.ProtoReader.ReadObject(Object value, Int32 key, ProtoReader reader) in D:\AqlaSerializer-v.2.0.1.1031\src\protobuf-net\ProtoReader.cs:line 773
   at AqlaSerializer.Serializers.CompiledSerializer.AqlaSerializer.Serializers.IProtoSerializer.Read(Object value, ProtoReader source) in D:\AqlaSerializer-v.2.0.1.1031\src\protobuf-net\Serializers\CompiledSerializer.cs:line 74
   at AqlaSerializer.Meta.RuntimeTypeModel.Deserialize(Int32 key, Object value, ProtoReader source, Boolean isRoot) in D:\AqlaSerializer-v.2.0.1.1031\src\protobuf-net\Meta\RuntimeTypeModel.cs:line 1080
   at AqlaSerializer.Meta.TypeModel.DeserializeCore(ProtoReader reader, Type type, Object value, Boolean noAutoCreate, Boolean isRoot) in D:\AqlaSerializer-v.2.0.1.1031\src\protobuf-net\Meta\TypeModel.cs:line 819
   at AqlaSerializer.Meta.TypeModel.Deserialize(Stream source, Object value, Type type, Int64 length, SerializationContext context) in D:\AqlaSerializer-v.2.0.1.1031\src\protobuf-net\Meta\TypeModel.cs:line 779
   at AqlaSerializer.Meta.TypeModel.Deserialize(Stream source, Object value, Type type, SerializationContext context) in D:\AqlaSerializer-v.2.0.1.1031\src\protobuf-net\Meta\TypeModel.cs:line 703
   at AqlaSerializer.Meta.TypeModel.Deserialize(Stream source, Object value, Type type) in D:\AqlaSerializer-v.2.0.1.1031\src\protobuf-net\Meta\TypeModel.cs:line 689
   at AqlaSerializer.Serializer.Deserialize(Type type, Stream source) in D:\AqlaSerializer-v.2.0.1.1031\src\protobuf-net\Serializer.cs:line 123

  This exception was originally thrown at this call stack:
    AqlaSerializer.NetObjectCache.GetKeyedObject(int, bool) in NetObjectCache.cs
    AqlaSerializer.NetObjectHelpers.ReadNetObject_End(object, AqlaSerializer.NetObjectHelpers.ReadReturnValue, AqlaSerializer.ProtoReader, object, System.Type, AqlaSerializer.BclHelpers.NetObjectOptions) in NetObjectHelpers.Read.cs
    AqlaSerializer.Serializers.CompiledSerializer.AqlaSerializer.Serializers.IProtoSerializer.Read(object, AqlaSerializer.ProtoReader) in CompiledSerializer.cs
    AqlaSerializer.Meta.RuntimeTypeModel.Deserialize(int, object, AqlaSerializer.ProtoReader, bool) in RuntimeTypeModel.cs
    AqlaSerializer.ProtoReader.ReadTypedObject(object, int, AqlaSerializer.ProtoReader, System.Type) in ProtoReader.cs
    AqlaSerializer.ProtoReader.ReadObject(object, int, AqlaSerializer.ProtoReader) in ProtoReader.cs
    AqlaSerializer.Serializers.CompiledSerializer.AqlaSerializer.Serializers.IProtoSerializer.Read(object, AqlaSerializer.ProtoReader) in CompiledSerializer.cs
    AqlaSerializer.Meta.RuntimeTypeModel.Deserialize(int, object, AqlaSerializer.ProtoReader, bool) in RuntimeTypeModel.cs
    AqlaSerializer.ProtoReader.ReadTypedObject(object, int, AqlaSerializer.ProtoReader, System.Type) in ProtoReader.cs
    AqlaSerializer.ProtoReader.ReadObject(object, int, AqlaSerializer.ProtoReader) in ProtoReader.cs
    ...
AqlaSolutions commented 2 years ago

Hi, without a reproducable example it's impossible to say what's going on.

inethui commented 2 years ago

The setup is complicated and involves many core business objects in our system. So I don't know how to create a reproducible example for you to take a look. However, I can debug into Aqla, are there some classes or methods I should watch closely in order to trouble shoot this issue?

inethui commented 2 years ago

In deserialization, does Aqla follow the object reference chain? For example, if class A has a field "b" which reference class B, would Aqla deserialize B before finish up deserializing A?

inethui commented 2 years ago

I noticed that there are two kinds of call stacks in deserialization:

AqlaSerializer.Serializers.CompiledSerializer.AqlaSerializer.Serializers.IProtoSerializer.Read Line 74
AqlaSerializer.Meta.RuntimeTypeModel.Deserialize Line 1080
AqlaSerializer.ProtoReader.ReadTypedObject Line 787
AqlaSerializer.ProtoReader.ReadObject Line 773

and

AqlaSerializer.NetObjectCache.GetKeyedObject Line 46
AqlaSerializer.NetObjectHelpers.ReadNetObject_End Line 37

The second one is the failed one. Does this indicate something abnormal?

AqlaSolutions commented 2 years ago

The setup is complicated and involves many core business objects in our system. So I don't know how to create a reproducible example for you to take a look.

Try removing fields one by one until you find which one causes this. Then you can make a reproducable example to post here.

This exception tells that there is an attempt to retrieve object reference which was not constructed yet. It's impossible to say anything more from the compiled stacktrace. At least you should try disabling RuntimeTypeModel.AutoCompile.

I would put a few breakpoints inside NetObjectHelpers methods to understand what's going on. You can also make use of RuntimeTypeModel.GetDebugSchema method to understand the structure of serializers.

In deserialization, does Aqla follow the object reference chain? For example, if class A has a field "b" which reference class B, would Aqla deserialize B before finish up deserializing A?

Usually yes but there is an index of all keyed objects at the start of stream unless you use some switches of ProtoCompatibility.

inethui commented 2 years ago

I figured this out, it's a problem on our side. Thanks a lot for the help!