Skip to content
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

Added updatable timer sample. #167

Merged
merged 4 commits into from
Apr 1, 2025
Merged

Conversation

mfateev
Copy link
Member

@mfateev mfateev commented Mar 29, 2025

What was changed

Added updatable_timer sample based on the Java one.

Why?

It demonstrates how to use workflow.wait_condition with a timeout. How to update the sleep interval is a FAQ.

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.

May also want a simple test on this one

Copy link
Member

Choose a reason for hiding this comment

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

Like our other samples w/ no special install instructions, may want to link to top-level README for "prerequisites"

Comment on lines 9 to 27
@workflow.defn
class Workflow:
def __init__(self):
self.timer: Optional[UpdatableTimer] = None

@workflow.run
async def run(self, wake_up_time: float):
self.timer = UpdatableTimer(
datetime.fromtimestamp(wake_up_time, tz=timezone.utc)
)
await self.timer.sleep()

@workflow.signal
async def update_wake_up_time(self, wake_up_time: float):
# Deals with situation when the signal method is called before the run method.
# This happens when a workflow task is executed after a signal is received
# or when a workflow is started using the signal-with-start.
await workflow.wait_condition(lambda: self.timer is not None)
assert self.timer is not None # for mypy
Copy link
Member

Choose a reason for hiding this comment

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

We have a neat, fairly new feature for @workflow.init that lets you operate on workflow input on the constructor, so can change this to:

Suggested change
@workflow.defn
class Workflow:
def __init__(self):
self.timer: Optional[UpdatableTimer] = None
@workflow.run
async def run(self, wake_up_time: float):
self.timer = UpdatableTimer(
datetime.fromtimestamp(wake_up_time, tz=timezone.utc)
)
await self.timer.sleep()
@workflow.signal
async def update_wake_up_time(self, wake_up_time: float):
# Deals with situation when the signal method is called before the run method.
# This happens when a workflow task is executed after a signal is received
# or when a workflow is started using the signal-with-start.
await workflow.wait_condition(lambda: self.timer is not None)
assert self.timer is not None # for mypy
@workflow.defn
class Workflow:
@workflow.init
def __init__(self, wake_up_time: float) -> None:
self.timer = UpdatableTimer(
datetime.fromtimestamp(wake_up_time, tz=timezone.utc)
)
@workflow.run
async def run(self, wake_up_time: float) -> None:
await self.timer.sleep()
@workflow.signal
async def update_wake_up_time(self, wake_up_time: float):

(also can remove the assert self.timer is not None # for mypy in the query)

Copy link
Member Author

Choose a reason for hiding this comment

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

Nice! So much clearer!


@workflow.defn
class Workflow:
def __init__(self):
Copy link
Member

Choose a reason for hiding this comment

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

Recommend return type annotations everywhere

Copy link
Member Author

Choose a reason for hiding this comment

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

My Java brain protested this for a constructor :).

Refactored workflow to use workflow.init.
Added unit test.
@cretz cretz merged commit 7577bd6 into temporalio:main Apr 1, 2025
10 checks passed
@mfateev mfateev deleted the updatable-timer branch April 1, 2025 20:21
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.

None yet

2 participants