akkadotnet / Hyperion

Polymorphic serialization for .NET
Apache License 2.0
277 stars 62 forks source link

Version tolerance is not working under CoreClr #60

Open kantora opened 7 years ago

kantora commented 7 years ago

I am testing the Akka Cluster update process. I have two nodes with the only difference that they have different assembly versions (with the same code). One "old" node has version 0.0.0-local assemblies and the new node has 0.0.1-local ones.

I am running everything under net-core under ubuntu (Akka.Net 1.3.0). Also, I've made custom Hyperion build with net-core support and Akka.Serialization.Hyperion with core support so cluster is running well.

So after updating assembly version numbers on on of the nodes I receive this error messages on the "old" node:

 File name: 'ClusterKit.API.Client, Version=0.0.1.0, Culture=neutral, PublicKeyToken=null'
    at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMarkHandle stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName, ObjectHandleOnStack type, ObjectHandleOnStack keepalive)
    at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName)
    at System.RuntimeType.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark)
    at System.Type.GetType(String typeName, Boolean throwOnError)
    at Hyperion.Extensions.TypeEx.<>c.<GetTypeFromManifestName>b__27_0(ByteArrayKey b)
    at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
    at Hyperion.Extensions.TypeEx.GetTypeFromManifestVersion(Stream stream, DeserializerSession session)
    at Hyperion.Serializer.GetDeserializerByManifest(Stream stream, DeserializerSession session)
    at Hyperion.Serializer.Deserialize[T](Stream stream)
    at Akka.Serialization.HyperionSerializer.FromBinary(Byte[] bytes, Type type)
    at Akka.Serialization.Serialization.Deserialize(Byte[] bytes, Int32 serializerId, String manifest)
    at Akka.Remote.Serialization.MessageContainerSerializer.FromBinary(Byte[] bytes, Type type)
    at Akka.Serialization.Serialization.Deserialize(Byte[] bytes, Int32 serializerId, String manifest)
    at Akka.Remote.DefaultMessageDispatcher.Dispatch(IInternalActorRef recipient, Address recipientAddress, Payload message, IActorRef senderOption)
    at lambda_method(Closure , Object , Action`1 , Action`1 , Action`1 )
    at Akka.Actor.ReceiveActor.ExecutePartialMessageHandler(Object message, PartialAction`1 partialAction)
    at Akka.Actor.UntypedActor.Receive(Object message)
    at Akka.Actor.ActorBase.AroundReceive(Receive receive, Object message)
    at Akka.Actor.ActorCell.ReceiveMessage(Object message)
    at Akka.Actor.ActorCell.Invoke(Envelope envelope)
 --- End of stack trace from previous location where exception was thrown ---
    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
    at Akka.Actor.ActorCell.HandleFailed(Failed f)
    at Akka.Actor.ActorCell.SysMsgInvokeAll(EarliestFirstSystemMessageList messages, Int32 currentState)

The main problem with futher debugging is that I could not manage to load Hyperion solution properly under VS2017 (is there any instruction to correctly load Hyperion.FSharpTestTypes?). Meanwhile, build scripts are working well.

Any advice of fixing issue? Thanks.

kantora commented 7 years ago

Em... guys...

        public static string GetShortAssemblyQualifiedName(this Type self)
        {
            var name = self.AssemblyQualifiedName;
            name = name.Replace(CoreAssemblyName, ",%core%");
            name = name.Replace(", Culture=neutral", "");
            name = name.Replace(", PublicKeyToken=null", "");
            name = name.Replace(", Version=1.0.0.0", ""); //TODO: regex or whatever...
            return name;
        }

So this is the cause I could not reproduce bug in hyperion tests...

kantora commented 7 years ago

I will make a PR

Aaronontheweb commented 6 years ago

Running into a version of this issue on the Akka.NET project itself:

System.InvalidCastException : [A]System.Collections.Immutable.ImmutableDictionary`2[System.String,Akka.DistributedData.VersionVector] cannot be cast to [B]System.Collections.Immutable.ImmutableDictionary`2[System.String,Akka.DistributedData.VersionVector]. Type A originates from 'System.Collections.Immutable, Version=1.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' in the context 'Default' at location 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\1.1.2\System.Collections.Immutable.dll'. Type B originates from 'System.Collections.Immutable, Version=1.2.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' in the context 'Default' at location 'D:\work\edbce350daf6a08d\src\contrib\cluster\Akka.DistributedData.Tests\bin\Release\netcoreapp1.1\System.Collections.Immutable.dll'.
   at lambda_method(Closure , Stream , DeserializerSession )
   at lambda_method(Closure , Stream , DeserializerSession )
   at Akka.DistributedData.Serialization.ReplicatedDataSerializer.FromBinary(Byte[] bytes, Type type) in D:\work\edbce350daf6a08d\src\contrib\cluster\Akka.DistributedData\Serialization\ReplicatedDataSerializer.cs:line 66
   at Akka.DistributedData.Tests.Serialization.ReplicatedDataSerializerSpec.CheckSerialization[T](T expected) in D:\work\edbce350daf6a08d\src\contrib\cluster\Akka.DistributedData.Tests\Serialization\ReplicatedDataSerializerSpec.cs:line 232
   at Akka.DistributedData.Tests.Serialization.ReplicatedDataSerializerSpec.ReplicatedDataSerializer_should_serialize_ORSet_delta() in D:\work\edbce350daf6a08d\src\contrib\cluster\Akka.DistributedData.Tests\Serialization\ReplicatedDataSerializerSpec.cs:line 80