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

[RFC] Remove UnifiedMessages reflection usage #1433

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

affederaffe
Copy link

This PR tries to remove the last directly existing reflection usage in SteamUnifiedMessages.
The protobuf code generator was updated instead to directly handle the messaging.
Obviously this is a breaking change, but, at least in my opinion, necessary in order to fully remove reflection.

@xPaw
Copy link
Member

xPaw commented Sep 18, 2024

I like the idea. If you enable the trimming warnings, what warnings are reported? In particular handling of incoming messages.

Do note that protobuf.net is heavily reflection based, so that doesn't help us with AOT/trimming atm.

ctx.WriteLine( $"public AsyncJob<SteamUnifiedMessages.ServiceMsg<{Escape( method.OutputType[1..] )}>> {Escape( method.Name )}({Escape( MakeRelativeName( ctx, method.InputType ) )} request)" )
.WriteLine( "{" )
.Indent()
.WriteLine( $"return UnifiedMessages.SendMessage<{Escape( MakeRelativeName( ctx, method.InputType ) )}, {Escape( method.OutputType[1..] )}>( $\"{{SERVICE_NAME}}.{Escape( method.Name )}#1\", request );" )
Copy link
Member

@xPaw xPaw Sep 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd remove {SERVICE_NAME} and just make it a const string.

Also can be simplified by using => instead of { return ... }

@affederaffe
Copy link
Author

I like the idea. If you enable the trimming warnings, what warnings are reported? In particular handling of incoming messages.

Do note that protobuf.net is heavily reflection based, so that doesn't help us with AOT/trimming atm.

There seem to be no more trimming warnings aside from protobuf.net usage. I'll try to see how to avoid these too soon ™️

@xPaw
Copy link
Member

xPaw commented Sep 18, 2024

@yaakov-h was also looking at that, and arrived at the conclusion that switching to google.protobuf is probably the way to go.

@xPaw
Copy link
Member

xPaw commented Sep 18, 2024

I don't however like calling CanHandleMsg for every single interface, maybe registration and a dictionary lookup would work better.

See 807fa51 for previous attempt at that.

@affederaffe
Copy link
Author

I don't however like calling CanHandleMsg for every single interface, maybe registration and a dictionary lookup would work better.

See 807fa51 for previous attempt at that.

It's not really every interface, only for currently created services (until they are disposed that is).
A dictionary could actually be worse for memory usage I imagine, but that'd need testing

@xPaw
Copy link
Member

xPaw commented Sep 18, 2024

Right I see it only goes through the registered services. But it calls CanHandleMsg for every service so it does the parsing for every one of these.

The handlers list could be a dictionary of <service name, handler>, so that you can parse the method name, and directly check if a handler is registered for a particular service.

@yaakov-h
Copy link
Member

This is a very different approach to the one I was looking at, and I do like it.

Keep in mind that consumers should be able to generate and run additional services (e.g. from updated protobufs) so some of those internal methods would need to be public.

Regarding the discussion above, perhaps each service should expose its name as a public property, then we can parse the service name once and invoke any matching handlers?

However, yes, for full trimming support and AOT we will almost certainly need to switch to Google.Protobuf. I haven't spiked AOT w/ Google just yet, but even manually hand-writing serializers and deserializers with protobuf-net.Core triggered trim and AOT warnings because it is annoyingly dependent on dynamic coding APIs.

@xPaw
Copy link
Member

xPaw commented Sep 19, 2024

perhaps each service should expose its name as a public property

Could add service name to UnifiedService, and then have HandleMsg( method, version, packet ) and then only call HandleMsg if the service name matches.

@xPaw
Copy link
Member

xPaw commented Sep 20, 2024

FYI this PR needs to rebase the protobufs submodule because its using an older commit.

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

Successfully merging this pull request may close these issues.

3 participants