Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MessagePack throws in Rhino environment when the same assembly is loaded multiple times #1821

Closed
Hanning-Liu opened this issue May 17, 2024 · 12 comments

Comments

@Hanning-Liu
Copy link

Hanning-Liu commented May 17, 2024

Bug description

I'm trying to use Rhino/Grasshopper, a 3d modeling and visual programming software, to send some Mesh geometry data via WIFI to another device.
And the MessagePack only works fine for the first time. Then keep reporting error.

Repro steps

You can see the video.

Expected behavior

No error message.

Actual behavior

Report error message: MessagePackSerializationException: Failed to serialize MyClass value.

  • Version used:

Rhino 8 currently support .NET Framework and .NET. But it needs a reboot to switch between these two platforms.
.NET 7 doesn't.
.NET Framework 4.8 works fine

Additional context

2024-05-17.13-43-24.mp4
@Hanning-Liu
Copy link
Author

I assume the error is related to memory use. Hope someone and help me!

@AArnott
Copy link
Collaborator

AArnott commented May 17, 2024

I don't think we can help you with merely a "MessagePackSerializationException: Failed to serialize MyClass value." as the reported error message.
If you can include the full callstack and all inner exceptions, there's a better chance we can help.

@Hanning-Liu
Copy link
Author

Thank you for your reply!

I can't find the full call stack. But I submitted an issue on the Rhino Forum: https://discourse.mcneel.com/t/get-an-error-when-using-c-script-component-to-get-nuget-package/182256/2

I will update this issue once I get any reply from there!

@Hanning-Liu
Copy link
Author

@AArnott
Hi, Here is a new reply by the developer of Rhino software. He talks about the possible reason.
https://discourse.mcneel.com/t/get-an-error-when-using-c-script-component-to-get-nuget-package/182256/10?u=hani_leo

The C# Script component continously re-compiles your code every time you make a change. This means that there is an unnamed assembly in memory for every time you have changed the C# script. Each one of these assemblies end up containing a Script_Instance and MyClass implementation.
The MessagePack library you are using in the example above has a dynamic type resolver that based on my quick inspection seem to get confused when the script is changed. It runs fine the first time, but on the second attempt (after editing the script and compiling a new assembly by the component backend), it gets confused on how to resolve and serialize the type MyClass. As I mentioned above this type is now in a completely different assembly but has the same name.
I did not dig deeper into the code behind this library. Here is the the inner exception stack. Seems like there is an exception in the static constructor of the FormatterCache type.

at MessagePack.Resolvers.DynamicObjectResolver.GetFormatter[T]()
   at MessagePack.Resolvers.StandardResolver.FormatterCache`1..cctor()
--- End of stack trace from previous location ---
   at MessagePack.FormatterResolverExtensions.Throw(TypeInitializationException ex)
   at MessagePack.MessagePackSerializer.Serialize[T](MessagePackWriter& writer, T value, MessagePackSerializerOptions options)
   at MessagePack.MessagePackSerializer.Serialize[T](T value, MessagePackSerializerOptions options, CancellationToken cancellationToken)
   at Script_Instance.RunScript(Object x, Object y, Object& a) in rhinocode:///grasshopper/1/bc8f6a2e-38f3-4a28-ab06-7ff244bd8d2a/93d481be-7cf3-445f-af65-5520b5cf9f99:line 63
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)

@AArnott
Copy link
Collaborator

AArnott commented May 19, 2024

I wonder if the assembly name changes each time it is recompiled and loaded.
If the assembly name is unique each time, I would expect this to work. But if Rhino loads a new assembly with the same name each time, then you're in a decidedly unsupported scenario.

@AArnott AArnott changed the title MessagePack only works fine for the first time. MessagePack throws in Rhino environment when the same assembly is loaded multiple times May 19, 2024
@Hanning-Liu
Copy link
Author

Based on what the developer of Rhino said, I think the assemblies have the same name.
And I think the bug should be fixed by the developer of Rhino. Since the C# script component recompiles each time the code is changed, the previously compiled assemblies are no longer useful and should not be stored in memory.

I will continue communicating on the McNeel forum. Thank you for your response!

@AArnott
Copy link
Collaborator

AArnott commented May 19, 2024

the previously compiled assemblies are no longer useful and should not be stored in memory.

This may be a runtime limitation. .NET Framework doesn't support unloading assemblies, and I don't think mono does either. The newer ".NET" supports assembly unloading under certain conditions. I wonder which of these Rhino is based on.
Even if supported, unloading the old assembly requires that all references to that assembly be in the same AssemblyLoadContext and unloaded with it. This means MessagePack itself would also have to be loaded into the same ALC and unloaded with it, since MessagePack retains references to all types that it serializes for perf reasons.

@Hanning-Liu
Copy link
Author

Hanning-Liu commented May 20, 2024

Rhino runs on .NET Framework on windows and mono on mac before version 8.

Now Rhino 8 on windows supports both .Net Framework 4.8 and .NET 7. I first tried run the MessagePack on .NET 7. But I get these errors, it can't find the attributes:
Untitled-1

So I changed the runtime to .NET Framework, and it only works for the first time as we talked

@AArnott
Copy link
Collaborator

AArnott commented May 20, 2024

The attributes not being found isn't a runtime error -- that's an issue with build. Apparently MessagePack.Annotations isn't being referenced by the compiler.

@Hanning-Liu
Copy link
Author

Yes, but this is weird. It can recognize all other package without this one.

@AArnott
Copy link
Collaborator

AArnott commented May 20, 2024

No denying it's weird... I'm just saying this isn't a MessagePack bug. Rhino is the odd one out here where all the issues are occurring, and MessagePack has proper dependencies between packages so that you shouldn't be getting attribute not found compiler errors, so all arrows point to Rhino being the problem and not something we can support. Sorry.

@AArnott AArnott closed this as not planned Won't fix, can't repro, duplicate, stale May 20, 2024
@Hanning-Liu
Copy link
Author

Thank you for your help! I will continue communicating with Rhino developers!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants