Open BentTranberg opened 5 years ago
@BentTranberg that's a good question - I'm going to guess that it's a Hyperion issue.
@Horusiath - any ideas what could be going on here?
I can only to try to reproduce it (tbh. if @BentTranberg could create a repoducible example, that would be super) - Hyperion uses UTF8 for all strings, so specific names shouldn't be a problem.
In UTF8 these letters are encoded with two bytes. It is a rather common mistake to confuse string length and byte length. There are also other pitfalls related to handling of UTF8 strings that doesn't contain just "plain ASCII". These were my first thoughts.
I can try to create a reproducible example from the VS-solution with the problem, but I don't have the time to do it soon, since I am totally overwhelmed by work. I'm hoping there's a quicker way to provoke this error. Are there calls that can be used just to serialize the message, in the hope it will trigger the exception? Or can Hyperion be used to send from one actor to another in the same test program, just to simplify a bit?
I got another similar error today, in the same spot in the system. That in itself is suspicious. There's no source in the vicinity that I would suspect can corrupt anything. It looks like I need to dig into this sooner than I planned yesterday. As you can see from the error message, today it is likely the "Å" in a type name that causes it. About to start digging.
[ERROR][26.09.2019 08:34:13][Thread 0015][[akka://client/system/endpointManager/reliableEndpointWriter-akka.tcp%3A%2F%2Ftre%40127.0.0.1%3A29210-1/endpointWriter#1960773132]] AssociationError [akka.tcp://client@localhost:3431] -> akka.tcp://tre@127.0.0.1:29210: Error [Unable to cast object of type 'StoppÅrsakNr' to type 'System.String'.] [ ved Akka.Remote.EndpointReader.<Reading>b__11_1(InboundPayload inbound)
ved lambda_method(Closure , Object , Action`1 , Action`1 , Action`1 )
ved Akka.Tools.MatchHandler.PartialHandlerArgumentsCapture`4.Handle(T value)
ved Akka.Actor.ReceiveActor.ExecutePartialMessageHandler(Object message, PartialAction`1 partialAction)
ved Akka.Actor.UntypedActor.Receive(Object message)
ved Akka.Actor.ActorBase.AroundReceive(Receive receive, Object message)
ved Akka.Actor.ActorCell.ReceiveMessage(Object message)
ved Akka.Actor.ActorCell.Invoke(Envelope envelope)]
Cause: Unknown
Note: I deleted my last message where I had gotten the facts from my testing very wrong. I have now implemented the workaround, and everything is working well. So to get the facts straight:
The problem did not only occur on my machine, and it was always present.
The problem occured with two independent messages, where a record within the message structure had a field name that started with the letter "Å". Changing those field names to start with "Aa" instead, so that each entire record only had fields with "ascii names", solved the problem.
I noticed in WireShark that type names of fields that contain "Å" are streamed just fine. It seems it's the field names that can't have "Å", at least not in the start.
Some more test results, from a quick test.
I tried with various "special" unicode characters instead of "Å" in the first position. All caused exceptions.
Then I tried with various "special" unicode characters elsewhere after the first character in the field name. No problems. So I thought, ok, seems like I have a basis for a good workaround - using the type name also as the field name, because it doesn't start with "Å". Like this.
StoppÅrsakNr: StoppÅrsakNr option
This failed. Darn! Could it be that the field name somehow clashed with the type name? So I tried StoppØrsakNr: StoppÅrsakNr option
just to make sure, and there was still exceptions.
I tried various other naming patterns, but didn't succeed in finding a specific pattern that caused failure, other than what is already described.
The exceptions seem to be slightly different now and then. For example Unable to cast object of type 'StoppKilde' to type 'Microsoft.FSharp.Core.FSharpOption'1[TdTypes.Stopptider+StoppÅrsakNr]
, so it seems to get confused in various ways.
Turns out that on my development machine at home, this problem doesn't occur at all, and the difference is in the machine and not the program, because I even tested the same binaries too. The machines have both been installed by me, and I take great care making sure the environment is as equal as can reasonably be.
I will be working on a repro, as soon as my work situation permits.
Updated from Hyperion 0.9.8 to 0.9.9, and it did not resolve this issue.
Ported my applications from .NET Framework to .NET Core 3.1, and the issue is still unresolved. I still intend to create a repro as soon as I can find some time to do it, and I am heigthening the priority on that task.
Tested with Akka 1.3.17, Akka.FSharp 1.3.17, Akka.Remote 1.3.17, Akka.Serialization.Hyperion 1.3.13-beta, Hyperion 0.9.11.
Tested with Akka 1.4.0-beta3, Akka.FSharp 1.4.0-beta3, Akka.Remote 1.4.0-beta3, Akka.Serialization.Hyperion 1.4.0-beta3, Hyperion 0.9.11.
Akka, Akka.FSharp, Akka.Remote and Akka.Serialization.Hyperion, versions 1.3.13 through 1.4.0-beta2.
Message sent between two .NET Framework 4.6.2 applications. Message contains an F# record with a list of records of type Stopptid.
The type Stopptid has a field named ÅrsakNr. It appears the letter "Å" is causing trouble for the streaming of the message. If that field is renamed to AarsakNr (we use double a when å is not available), then there is no error in the streaming. Also, if the list of Stopptid is empty, there is also no error even if the name of the field is still ÅrsakNr with an initial Å.
This is the error message:
It says "Unable to cast object of type 'StopptidId' to type 'Microsoft.FSharp.Core.FSharpOption`1[System.DateTime]'."
Why is it trying to cast StopptidId to a DateTime? Obviously that special unicode character - Å - is causing the streaming to derail in some way in this particular case.
I've been using Akka.NET and letters like æøåÆØÅ for years, and haven't had any problems until now. I expect this to work, so this must be a rare bug.