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

Source generated actor clients #1165

Merged
merged 48 commits into from
Feb 16, 2024

Conversation

philliphoff
Copy link
Contributor

Description

Adds a .NET source generator that can be used to generate strongly-typed clients for interacting with actors, per proposal in #1158.

Changes include:

  • Adds a separate Dapr.Actors.Generators NuGet package that contains the source generator
  • Adds a unit test project, Dapr.Actors.Generators.Test for the source generator
  • Adds a separate E2E test project Dapr.E2E.Test.Actors.Generators
  • Adds a new example for using the source generator

Strongly-typed clients are generated by:

  1. Referencing the Dapr.Actors.Generators NuGet package.

    <Project>
      <ItemGroup>
         <PackageReference Include="Dapr.Actors.Generators" Version="x.x.x" />
      </ItemGroup>
    </Project>
  2. Add the Dapr.Actors.Generators.GenerateActorClientAttribute to the actor interface.

    using Dapr.Actors.Generators;
    
    namespace Sample;
    
    internal sealed record SampleState(string Value);
    
    [GenerateActorClient]
    internal interface ISampleActor
    {
        [ActorMethod(Name = "GetState")]
        Task<SampleState> GetStateAsync(CancellationToken cancellationToken = default);
    
        [ActorMethod(Name = "SetState")]
        Task SetStateAsync(SampleState state, CancellationToken cancellationToken = default);
    }

    The Dapr.Actors.Generators.ActorMethodAttribute can be used to map interface methods definitions to specific actor methods should the names differ (e.g. the interface uses "Async" suffix common in .NET but the actor methods do not).

  3. A strongly-typed client will be generated that can be used to invoke actor methods.

    using Dapr.Actors;
    using Dapr.Actors.Client;
    using Sample;
    
    var proxy = ActorProxy.Create(ActorId.CreateRandom(), "SampleActor");
    
    using var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(30));
    
    var client = new SampleActorClient(proxy);
    
    var state = await client.GetStateAsync(cancellationTokenSource.Token);
    
    await client.SetStateAsync(new SampleState("Hello, World!"), cancellationTokenSource.Token);

Issue reference

We strive to have all PR being opened based on an issue, where the problem or feature have been discussed prior to implementation.

Please reference the issue this PR will close: #1158

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

Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
@codecov
Copy link

codecov bot commented Oct 12, 2023

Codecov Report

All modified and coverable lines are covered by tests ✅

Comparison is base (e244e88) 67.28% compared to head (cb28b7e) 67.28%.
Report is 1 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #1165   +/-   ##
=======================================
  Coverage   67.28%   67.28%           
=======================================
  Files         174      174           
  Lines        6025     6025           
  Branches      671      671           
=======================================
  Hits         4054     4054           
  Misses       1802     1802           
  Partials      169      169           
Flag Coverage Δ
net6 67.26% <ø> (ø)
net7 67.26% <ø> (ø)
net8 67.27% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@halspang
Copy link
Contributor

@philliphoff - Is this still a WIP or is it ready for review?

@philliphoff
Copy link
Contributor Author

philliphoff commented Nov 30, 2023

@halspang It's ready for review, assuming the parent proposal is accepted without significant changes. (Happy to have feedback, but I know the maintainers have been busy with other things.)

And I'll need to look into the CI failures.

Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
@philliphoff philliphoff marked this pull request as ready for review December 4, 2023 21:31
@philliphoff philliphoff requested review from a team as code owners December 4, 2023 21:31
@philliphoff
Copy link
Contributor Author

The remaining integration test failures seems to be a preexisting flaky actor timer test. (It's also failing for PRs that make no code changes.)

Signed-off-by: Phillip Hoff <phillip@orst.edu>
@philliphoff philliphoff changed the title WIP: Source generated actor clients Source generated actor clients Dec 4, 2023
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Copy link
Contributor

@halspang halspang left a comment

Choose a reason for hiding this comment

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

Overall, this looks great. Not super familiar with code generation, but it makes sense as presented. Just a few questions but nothing really blocking except maybe the testing just to avoid duplication.

@halspang halspang merged commit c07eb69 into dapr:master Feb 16, 2024
10 checks passed
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.

Proposal: Strongly-typed non-remoted Actor clients
2 participants