Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Expose root workflow execution #805

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

Merged
merged 4 commits into from
Mar 31, 2025
Merged

Expose root workflow execution #805

merged 4 commits into from
Mar 31, 2025

Conversation

THardy98
Copy link
Contributor

What was changed

Expose root workflow execution to workflow info (available from workflow info) and workflow execution info (available from workflow describe/list)

  1. Closes [Feature Request] Expose root workflow execution #774

  2. How was this tested:
    Updating existing info,describe,list tests.

  3. Any docs updates needed?
    Probably

@THardy98 THardy98 requested a review from a team as a code owner March 28, 2025 01:55
Comment on lines 2761 to 2765
root_id: Optional[str]
"""ID for the root workflow"""

root_run_id: Optional[str]
"""Run ID for the root workflow"""
Copy link
Member

Choose a reason for hiding this comment

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

So technically this is an incompatible change since users can technically instantiate this object themselves which some users may do in a mock client situation (I know they do in other languages). Two options:

  1. Add a note to the docstring of this class (and WorkflowExecutionDescription) that the constructor may change in backwards incompatible ways
  2. Add defaults for these values

I'm on the fence on which I prefer. @dandavison or @THardy98 - preference?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think I'd lean toward the latter while we can and introduce the former when we have to. I suppose default values for these fields would be None?

Copy link
Member

Choose a reason for hiding this comment

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

Yup

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added defaults

Copy link
Contributor Author

@THardy98 THardy98 Mar 28, 2025

Choose a reason for hiding this comment

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

Removed defaults - linter complains about having fields with default values before fields without defaults, and this class is inherited by WorkflowExecutionDescription below, making it annoying to fix. In any case, does it not default to None already, being Optional ?

Copy link
Member

@cretz cretz Mar 31, 2025

Choose a reason for hiding this comment

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

Just move the fields to the bottom. I know this breaks our alphabetical order, but new fields with defaults being at the bottom makes the most sense anyways, we just happen to have alphabetical order because we have never added a field with a default before. No, that the data type is Optional is unrelated to whether the field has to be specified on construction or not.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes but it still conflicts with the non-defaults fields in WorkflowExecutionDescription, unless I'm misunderstanding you

Copy link
Member

Choose a reason for hiding this comment

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

Oh, I see, even moving to the bottom of WorkflowExecution doesn't help with. Yeah if we were on Python > 3.10, I'd say mark the dataclasses as kw_only=True but since we can't do that, let's (for now) just leave them where they are and go with option 1 from my comment at the top of this thread which is "Add a note to the docstring of this class (and WorkflowExecutionDescription) that the constructor may change in backwards incompatible ways".

@@ -427,6 +427,7 @@ class Info:
headers: Mapping[str, temporalio.api.common.v1.Payload]
namespace: str
parent: Optional[ParentInfo]
root: Optional[RootInfo]
Copy link
Member

Choose a reason for hiding this comment

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

Can we have a test that confirms this is populated (and that it is populated on result of handle.describe() from client side)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added a test in test_workflow and added an assertion to a describe test in test_client

@THardy98 THardy98 force-pushed the expose_root_wf_exec branch from bf61320 to 36eea79 Compare March 28, 2025 21:37
@THardy98 THardy98 force-pushed the expose_root_wf_exec branch from 36eea79 to c94eb3b Compare March 28, 2025 21:48
@THardy98 THardy98 force-pushed the expose_root_wf_exec branch from c94eb3b to ab70dfa Compare March 28, 2025 22:03
@THardy98
Copy link
Contributor Author

skipping the test in time-skipping environments, needs temporalio/sdk-java#2441
which I suppose hasn't been released yet (or is not used in the Python SDK yet)

@@ -150,3 +156,25 @@ async def admitted_update_task(
lambda: workflow_update_exists(client, handle.id, id),
)
return update_task


async def child_started(
Copy link
Member

Choose a reason for hiding this comment

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

This does not seem related to child. Maybe a assert_workflow_exists_eventually helper instead? Also, this does not need to accept the workflow (just use get_workflow_handle which is untyped), but when changing to assert_workflow_exists_eventually you may want this so you can return a handle for the workflow instead of a bool.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

changed to assert_workflow_exists_eventually returns a WorkflowHandle (if exists)

Comment on lines 7071 to 7087
@workflow.defn(name="ChildWorkflowInfo")
class ChildWorkflowInfo:
def __init__(self) -> None:
self.blocked = True

@workflow.signal
def unblock(self):
self.blocked = False

@workflow.run
async def run(self):
await workflow.wait_condition(lambda: not self.blocked)
return workflow.info().root


@workflow.defn(name="WithChildWorkflowInfo")
class WithChildWorkflowInfo:
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
@workflow.defn(name="ChildWorkflowInfo")
class ChildWorkflowInfo:
def __init__(self) -> None:
self.blocked = True
@workflow.signal
def unblock(self):
self.blocked = False
@workflow.run
async def run(self):
await workflow.wait_condition(lambda: not self.blocked)
return workflow.info().root
@workflow.defn(name="WithChildWorkflowInfo")
class WithChildWorkflowInfo:
@workflow.defn
class ExposeRootChildWorkflow:
def __init__(self) -> None:
self.blocked = True
@workflow.signal
def unblock(self):
self.blocked = False
@workflow.run
async def run(self):
await workflow.wait_condition(lambda: not self.blocked)
return workflow.info().root
@workflow.defn
class ExposeRootWorkflow:

Don't need to manually set name on these, and would rather name the workflow similar to its test if at all possible

Copy link
Contributor Author

Choose a reason for hiding this comment

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

removed and renamed

self.blocked = False

@workflow.run
async def run(self):
Copy link
Member

Choose a reason for hiding this comment

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

Set return type hints on all non-test methods

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done.

"Java test server needs release with: https://github.com/temporalio/sdk-java/pull/2441"
)
async with new_worker(client, WithChildWorkflowInfo, ChildWorkflowInfo) as worker:
child_wf_id = "child-wf-id"
Copy link
Member

Choose a reason for hiding this comment

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

Taking this ID globally is not very safe ID for multiple executions of this test environment. Can you add a UUID in here somewhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yup, done

@THardy98 THardy98 requested a review from cretz March 31, 2025 18:31
Copy link
Member

@cretz cretz left a comment

Choose a reason for hiding this comment

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

Looks great, nothing blocking (still may be worth that dataclass constructor warning to users about constructor changing)

@THardy98 THardy98 merged commit 92b7758 into main Mar 31, 2025
14 checks passed
@THardy98 THardy98 deleted the expose_root_wf_exec branch March 31, 2025 19:54
@THardy98
Copy link
Contributor Author

TYFR :)

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.

[Feature Request] Expose root workflow execution
3 participants