Provide entity support for direct grpc connections to DTS#369
Provide entity support for direct grpc connections to DTS#369sebastianburckhardt merged 1 commit intomainfrom
Conversation
7f3fc0a to
8db3603
Compare
|
I am marking this as ready for review now that I have some tests passing. Given that iterations are slow, I want to run a lot more tests before merging though. |
|
LGTM |
| .Configure(additionalConfig ?? (_ => { })) | ||
| .ValidateDataAnnotations(); | ||
|
|
||
| builder.Services.AddOptions<DurableTaskClientOptions>(builder.Name) |
There was a problem hiding this comment.
I think there is a builder.Configure(optionsCallback) overload you can use
There was a problem hiding this comment.
yes, much better.
| /// automatically converted back and forth between the old DT Core representation (JSON-encoded external events) | ||
| /// and the new protobuf representation (explicit history events), which is used by the DTS scheduler backend. | ||
| /// </summary> | ||
| public bool ConvertOrchestrationEntityEvents { get; set; } |
There was a problem hiding this comment.
This value and InsertEntityUnlocksOnCompletion look like they are more implementation details and not a public API. I would prefer we figure out a way to make these non-public if possible. If this must be public due to different projects, then we should find a way to hide this in an .Internal namespace and add comments declaring this not meant for public consumption.
Here is an example: https://github.com/microsoft/durabletask-dotnet/blob/main/src/Abstractions/Internal/IOrchestrationSubmitter.cs
One idea would be to make these properties internal (maybe even in a sub-class to keep them together). Then add an extension method ConfigureForAzureManaged(this GrpcDurableTaskWorkerOptions options) under Microsoft.DurableTask.Worker.Grpc.Internal namespace with the comments. Then AzureManaged can call that.
There was a problem hiding this comment.
Would it be possible to use an "internals visible to" property so that only Worker.AzureManaged can access these options?
There was a problem hiding this comment.
Yes, you can do that for now. I did it in the Abstraction package:
Please just add a comment saying these are used by AzureManaged to treat them as public API breaking change rules
But I have since changed my stance on how much I like that (I don't recommend it anymore). The reason is this can still cause issues down the road. If customers use Worker.AzureManager/1.n which uses these cross-assembly internal properties, but also use Worker.Grpc/1.n+1 which has since removed these properties in a refactor, the app will throw method missing exceptions.
BUT given we already use this pattern in the code base, I think the comment will be good enough. Maybe in a v2.x we can rethink and remove this approach.
There was a problem hiding this comment.
I tried the "internals visible" approach and it worked but it is also causing some warnings (because there are conflicts between doubly defined classes, those come from files that are shared between the projects).
So I will instead do what you suggested before.
There was a problem hiding this comment.
I have modified the code so it now uses a private class InternalOptions, and offers a public extension method ConfigureForAzureManaged(this GrpcDurableTaskWorkerOptions options) like you suggested.
| /// Configure the worker to use the default settings for connecting to the Azure Managed Durable Task service. | ||
| /// </summary> | ||
| /// <param name="options">The gRPC worker options.</param> | ||
| public static void ConfigureForAzureManaged(this GrpcDurableTaskWorkerOptions options) |
There was a problem hiding this comment.
Can this be moved to the AzureManaged project? Code in the Grpc project is supposed to be backend-agnostic.
There was a problem hiding this comment.
This is based on a suggestion of mine. The properties being added in InternalOptions are specialized for AzureManaged scenario, but they need to be in the project. To avoid having these options that customer's are not expected to ever configure, we make the values themselves internal and only expose a single public point to configure them.
With that said, we can name this method more backend-agnostic, but it does need to remain in this project so it can access the internal properties. Additionally, we should include a disclaimer in the XML doc explaining this is considered an internal API surface and not subject to breaking change guarantees.
There was a problem hiding this comment.
I kept the name (we will confuse only ourselves if we invent more names) but there is now an XML doc that states that this is an internal API.
|
|
||
| // The point of this class is to reverse a Newtonsoft serialization that happened in prior DT code. | ||
| // To do this reliably we use the same Newtonsoft. | ||
| // This is not introducing a new dependency, and should be eliminated once the original dependency is eliminated. |
There was a problem hiding this comment.
Just to be clear, if we remove the DT.Core dependency from this SDK, will that also allow us to remove this dependency on Newtonsoft.Json?
There was a problem hiding this comment.
Yes. The point of this class is to "undo Newtonsoft serialization" that was unfortunately already done inside DT.Core. So the Newtonsoft dependency goes away when either (a) Newtonsoft dependency is removed from DT.Core, or (b) DT.Core dependency is removed.
|
@sebastianburckhardt you'll need to rebase this PR on the latest from main. We no longer use submodules for updating the protobuf definitions. See this change: #370. |
| using System.Collections.Generic; | ||
| using System.Text; | ||
|
|
||
| namespace Microsoft.DurableTask.Worker.Grpc.Internal; |
There was a problem hiding this comment.
Please move to an Internal folder.
src/Worker/Grpc/InternalOptions.cs
Outdated
| /// Options for controlling backend-specific features. These are not exposed directly, but can be accessed via | ||
| /// the extension methods in <see cref="Internal.InternalOptionsExtensions"/>. | ||
| /// </summary> | ||
| class InternalOptions |
There was a problem hiding this comment.
Consider doing one of the following:
- Make this a nested class in
GrpcDurableTaskWorkerOptions. - Or, rename to
InternalWorkerOptionsand move toInternalfolder (along with the extension class for it).
There was a problem hiding this comment.
I am making this a nested class.
| /// unlock events into the history when an orchestration terminates while holding an entity lock. | ||
| /// </summary> | ||
| public bool InsertEntityUnlocksOnCompletion { get; set; } | ||
| internal InternalOptions InternalOptions { get; set; } = new(); |
There was a problem hiding this comment.
I recommend removing the setter (unless it is needed)
| internal InternalOptions InternalOptions { get; set; } = new(); | |
| internal InternalOptions InternalOptions { get; } = new(); |
eng/proto
Outdated
There was a problem hiding this comment.
Will merge second-to-latest commit in main which introduced the vendor pattern.
There was a problem hiding this comment.
I rebased on latest main now so this is no longer there.
| /// <summary> | ||
| /// Provides access to configuring internal options for the gRPC worker. | ||
| /// </summary> | ||
| public static class InternalOptionsExtensions |
There was a problem hiding this comment.
Please include disclaimers as seen on this type: https://github.com/microsoft/durabletask-dotnet/blob/main/src/Abstractions/Internal/IOrchestrationSubmitter.cs
There was a problem hiding this comment.
I have added an XML comment on the extension method
eng/proto
Outdated
There was a problem hiding this comment.
For some reason this is still showing up. Will try to get rid of it.
3d04a45 to
0490d86
Compare
implements the necessary protocol conversions and configurations for providing entity support when connecting a DTS backend directly ("portable SDK").