-
Notifications
You must be signed in to change notification settings - Fork 64
ContinueAsNew works, needed to mark the orchestrator as completed #158
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
Conversation
|
@davidmrdavid, the reason why is because of how OutOfProc handles "uncompleted" orchestrations. It essentially just waits on that thread forever, meaning that even though the orchestration is effectively finished because it calls ContinueAsNew(), it won't treat the C# side of the replay as completed. See this code for a bit more detail: https://github.com/Azure/azure-functions-durable-extension/blob/dev/src/WebJobs.Extensions.DurableTask/Listener/OutOfProcOrchestrationShim.cs#L97. |
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.
LGTM, though we should validate isDone = true in the tests.
ConnorMcMahon
left a comment
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.
Disregard previous review, I have some new comments.
|
Heads up, this is already being validated in the tests. One of my changes is in the tests :) And I'll look to not return a Task |
|
@ConnorMcMahon , I rewrote the code such that it would enable |
ConnorMcMahon
left a comment
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.
I like the new approach, but I have some questions about the details of the new approach.
|
There seems to be some confusion about my helper function. I'll try to explain it below :) The
For case (1), Here, we return For case (2), we know that Said differently, here we return the Please let me know if you believe I should be adding more comments (or anything else) to make this clearer in the code :) |
|
I think we can simplify this given the dicussion we have had around not needing continueasnew to return a task? |
|
Hmm, it does not return a Task at the moment :) Happy to not even construct a Task though if that's what you're opposed to. I'm not entirely convinced that the Happy to also discuss verbally, I realize the Python SDK may look a little foreign, so perhaps the flow of data is not entirely clear. |
| self.generator = fn_output | ||
|
|
||
| else: | ||
| if not isinstance(fn_output, Iterator): |
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.
I inverted some if-else logic, which frees us from having to check for continue_as_new in so many places
|
|
||
| def _add_to_actions(self, generation_state): | ||
| # Do not add new tasks to action if continue_as_new was called | ||
| if self.durable_context.will_continue_as_new: |
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.
We do not add to the actions array if continue_as_new was called
| custom_status=self.durable_context.custom_status) | ||
|
|
||
| # No output if continue_as_new was called | ||
| if self.durable_context.will_continue_as_new: |
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.
we do not set output if continue_as_new was called
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.
This is mostly for consistency. I'm trying to avoid continue_as_new from sometimes returning something and sometimes not. Just to avoid subtle bugs
| return self._function_context | ||
|
|
||
| @property | ||
| def will_continue_as_new(self) -> bool: |
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.
This property alias exists just for readability
|
@ConnorMcMahon , I gave this one last refactor, I think it's a lot more readable and does not have the old, confusing, helper method. Let me know what you think and, if it looks good, please give it a thumbs up and GitHub so we can merge :) . Happy to take on more feedback though |
ConnorMcMahon
left a comment
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.
Much happier with this final iteration, it's very clear to me now :)
Addresses: #148
This PR fixes
continue_as_new, a feature that was failing silently before. Judging from the JS code, it appears thatcontinue_as_newactions should mark the orchestrator as "completed", and fixing this marker madecontinue_as_newwork as expected.Before merging, I could love some clarification on why this fix worked, which I believe must have to do with the expectations of
durable-extention. I still do not understand why this failed silently, as I was expecting, at least, some kind of "non-determinism" exception.