-
Notifications
You must be signed in to change notification settings - Fork 97
User metadata #701
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
User metadata #701
Conversation
d3712df
to
c7e1a83
Compare
50471eb
to
feebb86
Compare
@@ -3400,6 +3461,16 @@ def __init__( | |||
if pair.key.name in self.untyped_search_attributes: | |||
# We know this is mutable here | |||
del self.untyped_search_attributes[pair.key.name] # type: ignore | |||
self.static_summary = ( | |||
raw_info.user_metadata.summary |
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.
Isn't this a payload? I think you're going to have to change this up a bit to move all of the raw info conversion stuff into _from_proto
and make that method async def
. May also need a test that confirms schedule describe returns the same workflow summary/details it was created with.
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 working exactly the same way memo does when reading from raw info, for example. The tests that compare schedule before/after seem to confirm it works properly but I'll double check
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, now I see Optional[Union[str, temporalio.api.common.v1.Payload]]
, you're good
temporalio/converter.py
Outdated
@@ -1084,6 +1085,29 @@ async def encode_wrapper( | |||
""" | |||
return temporalio.api.common.v1.Payloads(payloads=(await self.encode(values))) | |||
|
|||
async def _encode_user_metadata( |
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.
Since this and the decode equivalent are only called from the client file, can they be made as just underscore-prefixed module-level helpers at the bottom of the client file?
callback: Callable[..., Any], | ||
*args: Any, | ||
context: Optional[contextvars.Context] = None, | ||
options: Optional[_TimerOptions] = None, |
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.
Pedantic, but I think it reads better if require this options
kwarg and move the _next_timer_options
extraction stuff to call_later
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.
Works for me
|
||
# The current details (as opposed to static details on workflow start), returned in the | ||
# metadata query | ||
self._current_details: str = "" |
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.
self._current_details: str = "" | |
self._current_details = "" |
(pedantic)
if summary | ||
else None | ||
) | ||
self._timer_impl( |
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.
There is nothing awaited here so I don't think this call is going to properly block. Internally I think asyncio invokes that callback on timer complete, so we need to block here waiting on that callback. I'd be ok using an asyncio.Event
that is awaited here and set in the callback (or a wait condition, I haven't sat to think about it tbh).
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.
Duh, thanks
def _temporal_workflow_metadata(self) -> temporalio.api.sdk.v1.WorkflowMetadata: | ||
query_definitions = [ | ||
temporalio.api.sdk.v1.WorkflowInteractionDefinition( | ||
name=qd.name if qd.name is not None else "", |
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.
name=qd.name if qd.name is not None else "", | |
name=qd.name or "", |
Pedantic, but this is probably good enough and may improve legibility
temporalio/workflow.py
Outdated
@overload | ||
def signal( | ||
*, | ||
description: str, | ||
unfinished_policy: HandlerUnfinishedPolicy = HandlerUnfinishedPolicy.WARN_AND_ABANDON, |
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 wonder if, instead of this new overload, you can just add description: Optional[str] = None
to the one above at line 223. Same for others, ideally you don't need a new overload for signal or update (you do for query because this is the first optional parameter overload)
return _Runtime.current().workflow_get_current_details() | ||
|
||
|
||
def set_current_details(description: str) -> None: |
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.
def set_current_details(description: str) -> None: | |
def set_current_details(current_details: str) -> None: |
Pedantic, but this isn't really a "description" per se
@@ -1091,8 +1166,29 @@ def uuid4() -> uuid.UUID: | |||
return uuid.UUID(bytes=random().getrandbits(16 * 8).to_bytes(16, "big"), version=4) | |||
|
|||
|
|||
async def sleep( |
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.
May want to update README (unsure if that would be just the Timers
section or also the Workflow Utilities
section), but don't have to
5270251
to
b156308
Compare
259c52e
to
594a5af
Compare
f85a76b
to
2d82ba9
Compare
2d82ba9
to
9fc0aa7
Compare
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. @dandavison - unsure if you want to look at this one
I'm coming cold to this, but maybe that's helpful as a simulation of a user encountering it. My initial reactions to the user-facing API are
|
This does match a pre-existing spec in the issue and names decided and merged in other SDKs, but we can still discuss...
Are you referring to workflow summary, timer summary, or activity summary? In this case we use the word "summary" like a JIRA issue might. There are also "details" which is the longer form ("summary" is the short form), but we didn't feel timers and activities needed details like workflows. It was the best word we could think of to represent this shared data across these (it's actually defined at https://github.com/temporalio/api/blob/38d2ac0af77602baf85c60678f4ab2c09ec47de0/temporal/api/sdk/v1/user_metadata.proto#L39-L43). In this case "summary" is a short-form summarizing what it is and is not related to when created.
Unfortunately yes to differentiate "static details" (static, set at start) from "current details" (can be set throughout the workflow), and then we chose "static summary" because it's just a short form of "static details". These are the best terms we could come up with to represent them and still avoid confusion (spec was relayed internally for feedback for many months, but we can still potentially revisit though this is already present in most other SDKs).
I assume this is for |
All of those. Yes these comments should have been made on the spec / design doc. My first thought is |
We want the concept of a "summary" to be a short form of text and "details" to be the long form. A "summary" isn't a "description" (arguably the "details" are more of a "description" than the "summary"). We decided there was no need for "details" for timer and activity at this time, only "summary". There is no concept of general purpose "user metadata" that a user can set, by intention, but the concept is user metadata and we may add more fields they can set in the future. |
What was changed
Why?
Checklist
Closes [Feature Request] Support user metadata #670
How was this tested:
Added & updated tests
Any docs updates needed?