-
Notifications
You must be signed in to change notification settings - Fork 273
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
Remove unecessary class constraint on startNew overload #2413
base: v2.x
Are you sure you want to change the base?
Remove unecessary class constraint on startNew overload #2413
Conversation
Merge dev to main for release 2.9.1
Promote dev to main for 2.9.2 release
@@ -141,8 +141,7 @@ public interface IDurableOrchestrationClient | |||
/// </exception> | |||
Task<string> StartNewAsync<T>( | |||
string orchestratorFunctionName, | |||
T input) | |||
where T : class; | |||
T input); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You may want to check the Git blame history for the previous change that introduced the class constraint. I vaguely remember that there was a reason this constraint was added, and it was to avoid some kind of breaking change related to multiple overloads of this method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, that seems to be this PR. The PR itself is to allow for mocking of APIs during testing. Unfortunately, the T : class
constraint is added in the first commit and not discussed explicitly on GitHub, so I'm not immediately sure why it was added.
I'll stare at the PR a bit longer, and see if there's any trace of a discussion about this internally;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The PR you're looking at only moved this method signature from one file to another. You'll have to go further back in time, looking at when this method signature was introduced originally in DurableContextExtensions.cs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, you're right - GitHub hid the deletion of content in DurableContextExtensions.cs
from me.
This seems to be real the PR that originates this constraint - #986, and then again on V2 here - #991
Context
Brandon describes this very case in the PR itself. In short - this constraint was introduced to allow an orchestration instanceID to be specified without that string being treated as the orchestration input itself.
Before that PR, if you had startNew("MyOrch", "myInstanceId")
then "myInstanceId" would become the orchestrator input instead of the instanceID due to an overload of signature startNew(name: string, input: object)
triggering.
So the fix was to introduce a generic overload and have that generic overload become what is required when a user wants to specify a string input but not the instanceID. So now, when a user wants to specify a string input but no instanceId, they need the "generic brackets <>and do
startNew("myOrch", "myInput"). and the standard
startNew without "generic brackets
always treats a second string parameter as the instanceId.
However:
I'm not immediately convinced that the T : class
was required to begin with. I think it should suffice just to create the generic-type overload, but I'll need to try it out. I'll make a few local tests on my end to validate. In the meantime, I'd be curious to know if @brandonh-msft remembers why that was added :) . There may be some reason I'm overlooking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup the reason was so that, in the absence of the parameter, we could pass null
(can't do that unless you type-constrain the generic to a class
). BUT, in the new land of <Nullable>
we can/should probably change this to just T?
and remove the constraint.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! That's a good idea. Enabling nullable analysis in this whole file (I understand the team is trying to do file-wide analyses when we enable nullable-checks) might take a bit of time, potentially making this a larger change. But I'll take a note about trying that out next :) .
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, converting to nullable usually has cascading effects - understood. Nevertheless, that's why the type constraint was there :) Alternatively, perhaps we could use default
instead of null
? Up to y'all ;)
Resolves: #1814
Related: #2348
Issue describing the changes in this PR
As highlighted in #1814, there's 2 generic overloads for
startNew
:First variant:
azure-functions-durable-extension/src/WebJobs.Extensions.DurableTask/ContextInterfaces/IDurableOrchestrationClient.cs
Lines 142 to 146 in ee2fba7
Second variant:
azure-functions-durable-extension/src/WebJobs.Extensions.DurableTask/ContextInterfaces/IDurableOrchestrationClient.cs
Line 163 in ee2fba7
You'll notice the first variant puts the constraint
T : class
whereas the first variant does not. This creates inconsistent type constraints on the same API. In particular, you may pass in a Tuple on the second variant but not in the first, as Tuples are structs not classes.This PR proposes removing the
T : class
constraint altogether. I'm using this PR as a conversation starter, given that we have not discussed this change yet.Pull request checklist
pending_docs.md
release_notes.md
/src/Worker.Extensions.DurableTask/AssemblyInfo.cs
Still pending:
Add to the
release_notes.md
. I would like to first get a thumbs up on the change, and see that the CI passes.