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

Bug/476 multiple methods per interface with JSON serialization doesn´t work #1343

Open
wants to merge 19 commits into
base: master
Choose a base branch
from

Conversation

paule96
Copy link

@paule96 paule96 commented Aug 28, 2024

Description

Now the Actor manager provides the MethodName for the serialization ActorMessageSerializersManager.
This makes it now possible for the JSON serialization to support Actor interfaces with more than one method defined in it.

As a side effect, this PR solves #1342 too.
Changes made in the dev container:

  • use docker-in-docker instead of docker-from-docker
    • now the devcontainer is isolated from the host and is not affected by the host configuration. But it also means accessing the dapr instance of the devcontainer is only accessible from inside the container.
  • install all dotnet sdks that the tests requires. (dotnet 6 is still the default, maybe we should change that too)
  • add the C# DevKit as an additional extension. This can be a breaking change for people that don't have a visual studio license and want to run the dev container on their local host. Users that run the dev container on GitHub get a license automatically injected.
  • Unblocks the localinit.sh script before running it

Changes made to the E2E Tests

  • it's now easier to debug failing start of the E2E test App.

Issue reference

It's part of the issue #476 starting with this comment.

It fixes also #1342

Checklist

Please make sure you've completed the relevant tasks for this PR, out of the following list:

  • Code compiles correctly
  • Created/updated tests
  • Extended the documentation
    • partly, I added at the interesting locations in the code comments.
    • This change shouldn't affect the current documented actor model, it just fixes a broken feature

cc @onionhammer as original contributor :)

@paule96
Copy link
Author

paule96 commented Aug 28, 2024

@onionhammer it would be nice if you could try out these changes. For me, it seems to not be possible yet. I will look the next days into #1342 to solve the debugging/contribution story for others.

I did found out what is wrong with the devcontainer setup :) Will fix both here. Of course the blind implementation was broken. Will be fixed in the next hour.

@paule96 paule96 force-pushed the bug/476_multiple_methods_per_interface_with_json_serialisation_doesntwork branch 2 times, most recently from f847e87 to a13100b Compare August 28, 2024 15:24
@paule96 paule96 marked this pull request as ready for review August 28, 2024 15:24
@paule96 paule96 requested review from a team as code owners August 28, 2024 15:24
@paule96
Copy link
Author

paule96 commented Aug 28, 2024

@onionhammer This is now ready to review :) That was a fun research. I tried to don't break existing code paths as much as I could.

Copy link
Contributor

@onionhammer onionhammer left a comment

Choose a reason for hiding this comment

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

This looks good to me, although I have no authority here :)

cc @halspang @shivamkm07

@WhitWaldo
Copy link
Contributor

WhitWaldo commented Sep 2, 2024

install all dotnet sdks that the tests requires. (dotnet 6 is still the default, maybe we should change that too)

.NET 7 fell out of support May 14 of this year and .NET 8 will do the same on November 10, 2024 with .NET 9 being introduced in the same time frame. That should be right around the 1.15 release, so I think there will be a good case to be made to drop .NET 6 and .NET 7 explicit support, target .NET 8 instead and include .NET 9 in the test suite for 1.16.

paule96 and others added 8 commits September 3, 2024 08:48
Signed-off-by: paule96 <paul-jeschke@outlook.com>
Signed-off-by: paule96 <paul-jeschke@outlook.com>
…terface

Signed-off-by: paule96 <paul-jeschke@outlook.com>
Now the devcontainer uses docker in docker, so you can reach the dapr setup after you did run dapr init. This will then only affect the dev container, without compromising the host of the devcontainer

Signed-off-by: paule96 <paul-jeschke@outlook.com>
Signed-off-by: paule96 <paul-jeschke@outlook.com>
Signed-off-by: paule96 <paul-jeschke@outlook.com>
Signed-off-by: paule96 <paul-jeschke@outlook.com>
Signed-off-by: paule96 <paul-jeschke@outlook.com>
@paule96 paule96 force-pushed the bug/476_multiple_methods_per_interface_with_json_serialisation_doesntwork branch from adb8471 to 7be9077 Compare September 3, 2024 08:48
@paule96
Copy link
Author

paule96 commented Sep 3, 2024

@WhitWaldo if I change the default version to dotnet 9.0 the new security vulnerability scanning of the dotnet CLI turns on implicitly and produces, of course, a lot of errors.

I guess the upgrading of the default SDK needs to be delayed.

maybe a separate issue is needed to clean up the solution of, the old tests, old implementation, and what else is connected to it. I guess the documentation needs to be updated too.
In that issue, the devcontainer shouldn't be forgotten.

So for now I would try to just update the default to dotnet 8.0 (support until November 10, 2026, it's LTS), and postpone the change to dotnet 9.0 to a later point in time.

@WhitWaldo
Copy link
Contributor

That's right - the plan is to put off changing the targeted releases until after the release of Dapr 1.15. There, we'll target .NET 6 and .NET 8 still, so no changes needed in the short term. But we'll put something prominent announcing EOL in the release notes so it's clear that in 1.16 we'll drop support for .NET 6 in favor of .NET 8 (and language version C# 12). An open question on that thread is whether we should go on targeting .NET 9 as well (though I'm also inclined to lean yes since there are frequently so many performance improvements in each).

You're right, that'll require some significant doc updates in addition to the other projects, but I've got a draft PR that'll likely handle the latter as I'm gradually adding nullability annotations throughout the .NET SDK and there are several other PRs in place that'll shift up some of the project layouts as well that'll help.

Things to tackle after the next release!

@paule96
Copy link
Author

paule96 commented Sep 12, 2024

@WhitWaldo do you know anybody I could ping to get a review? (maybe yourself)

@WhitWaldo
Copy link
Contributor

@paule96 I'm not a maintainer, so my check isn't worth a whole lot. I suspect this will get more attention as we edge closer to the 1.15 release and there's more of a general code freeze. If it hasn't been looked at closer to that timeline, I'll give it a look myself (for whatever it might be worth).

@yaron2
Copy link
Member

yaron2 commented Sep 26, 2024

cc @halspang @philliphoff

@paule96
Copy link
Author

paule96 commented Oct 7, 2024

@halspang & @philliphoff friendly reminder

@yaron2 yaron2 requested a review from WhitWaldo October 7, 2024 14:45
@WhitWaldo
Copy link
Contributor

WhitWaldo commented Oct 7, 2024

@paule96 I'm a maintainer now, so happy to give this a look!

I'm not already super familiar with how Dapr handles serialization under the hood, so I'm learning as I read through your changes here. The approach already taken registers the interface and references it throughout using an int, why it does this, I'm not entirely sure, but I'd assume it's to avoid name conflicts and shorten the amount of data passed around. If that's at all accurate, I'm concerned that this approach, which binds the serialization to the name of the method runs a risk of being insufficiently specific (especially in light of #1350 and the opportunity for polymorphic bindings reflecting the same method names).

Now, perhaps that's not a problem, as different interfaces should register different IDs and you're keying the serializers by both this interface and method. Perhaps you've considered this, but given your richer familiarity with the underlying problem space, does it make more sense to have a similar ID registry for the method names as we appear to have for the actor interfaces rather than the approach you've taken here?

Second, could you add some unit tests that prove that this approach works sufficiently well for method overloads?

@paule96
Copy link
Author

paule96 commented Oct 23, 2024

@WhitWaldo sorry for the late reply. Was kinda busy these days.
Thank you for pointing out the other pullrequest.

My first comment to overloads is:

It's not supported. Their is an explicit exception for that in the file:

private static void EnsureNotOverloaded(
string remotedInterfaceKindName,
Type remotedInterfaceType,
MethodInfo methodInfo,
ISet<string> methodNameSet)
{
if (methodNameSet.Contains(methodInfo.Name))
{
ThrowArgumentExceptionForMethodChecks(
remotedInterfaceKindName,
remotedInterfaceType,
methodInfo,
SR.ErrorRemotedMethodsIsOverloaded);
}
methodNameSet.Add((methodInfo.Name));
}

I will try to see what I can do to enable support for it. But I guess it will still work with names instead of Ids. The problematic part is, that we need to type match here. And because the transport types are json, it maybe becomes a challenge. (not sure yet)

And I can understand that actors get an "id". Because their polymorphy is possible. By the language design of methods I'm not aware of any function that will provide polymophic behavior to methods.

The only thing that I could see, if to trick around with inheritance, to like use the new modifier in a class for methods. But that would effectively not work in dapr actors space, because the actors are proxied with the interface, and the interface needs to point to an exact method and not to a new flagged method.

Maybe it resolves the need of chmod for it 🤷‍♀️

Signed-off-by: paule96 <paul-jeschke@outlook.com>
Signed-off-by: paule96 <paul-jeschke@outlook.com>
Signed-off-by: paule96 <paul-jeschke@outlook.com>
@paule96
Copy link
Author

paule96 commented Oct 24, 2024

@WhitWaldo I now have created the basic changes for method overloading. I will not push it to this branch or PR. The problem is, that by the design of the actors part of dapr, it doesn't seem to be supported.

For now I would put it on hold, but would like to know where we can find the framework independent documentation for dapr. Where you can see how dapr works outside of the SDK you use.
The reason is write now on my local changes, I changed the method name from:

yourcoolnamespace.evenbetterclassname.SuperFancyMethod

to:

yourcoolnamespace.evenbetterclassname.SuperFancyMethod()

or if it has parameters:

yourcoolnamespace.evenbetterclassname.SuperFancyMethod(FullNameOfParameterType, FullNameOfParameterType)

And I'm quite sure that this will be a breaking change, in special if you try to call an actor from example a python app.
But I couldn't find the documentation where this standards are documented

@WhitWaldo
Copy link
Contributor

@WhitWaldo I now have created the basic changes for method overloading. I will not push it to this branch or PR. The problem is, that by the design of the actors part of dapr, it doesn't seem to be supported.

For now I would put it on hold, but would like to know where we can find the framework independent documentation for dapr. Where you can see how dapr works outside of the SDK you use. The reason is write now on my local changes, I changed the method name from:

yourcoolnamespace.evenbetterclassname.SuperFancyMethod

to:

yourcoolnamespace.evenbetterclassname.SuperFancyMethod()

or if it has parameters:

yourcoolnamespace.evenbetterclassname.SuperFancyMethod(FullNameOfParameterType, FullNameOfParameterType)

And I'm quite sure that this will be a breaking change, in special if you try to call an actor from example a python app. But I couldn't find the documentation where this standards are documented

The actor runtime itself is in dapr/dapr, but I don't know that there's any specific documentation available that details any of it. As I understand it, it works similarly under the hood to Orleans (well, sort of) and Service Fabric Actors (closer)

@paule96
Copy link
Author

paule96 commented Oct 29, 2024

@WhitWaldo so can we skip the topic for now on this pullrequest and maybe open a new issue for method overloading? Because that was not scope of this PR

@WhitWaldo
Copy link
Contributor

@paule96 I agree method overloading isn't in scope, but I'm concerned about the opportunity for developers attempt to do so and then run into an odd runtime experience (as happens where with more than one method per interface).

I'm going to review this again this week and see if we can't get it merged as-is.

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

Successfully merging this pull request may close these issues.

4 participants