Skip to content

Tweak cancellation sample output #214

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 21 additions & 7 deletions hello/hello_cancellation.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import asyncio
import time
import traceback
from concurrent.futures import ThreadPoolExecutor
from datetime import timedelta
from typing import NoReturn

from temporalio import activity, workflow
from temporalio.client import Client, WorkflowFailureError
from temporalio.exceptions import CancelledError
from temporalio.exceptions import ActivityError, CancelledError
from temporalio.worker import Worker


Expand All @@ -20,8 +19,10 @@ def never_complete_activity() -> NoReturn:
print("Heartbeating activity")
activity.heartbeat()
time.sleep(1)
except CancelledError:
print("Activity cancelled")
except CancelledError as err:
print(
f"Got expected exception in activity. Cause chain is {format_exception_cause_chain(err)}"
)
raise


Expand All @@ -43,6 +44,11 @@ async def run(self) -> None:
# Always set a heartbeat timeout for long-running activities
heartbeat_timeout=timedelta(seconds=2),
)
except ActivityError as err:
print(
f"Got expected exception in workflow. Cause chain is {format_exception_cause_chain(err)}"
)
raise
finally:
await workflow.execute_activity(
cleanup_activity, start_to_close_timeout=timedelta(seconds=5)
Expand All @@ -61,7 +67,6 @@ async def main():
activities=[never_complete_activity, cleanup_activity],
activity_executor=ThreadPoolExecutor(5),
):

# While the worker is running, use the client to start the workflow.
# Note, in many production setups, the client would be in a completely
# separate process from the worker.
Expand All @@ -80,8 +85,17 @@ async def main():
try:
await handle.result()
raise RuntimeError("Should not succeed")
except WorkflowFailureError:
print("Got expected exception: ", traceback.format_exc())
except WorkflowFailureError as err:
print(
f"Got expected exception in client. Cause chain is {format_exception_cause_chain(err)}"
)


def format_exception_cause_chain(err: BaseException) -> str:
causes = [err]
while cause := causes[-1].__cause__:
causes.append(cause)
return " -> ".join([f"{e.__class__.__name__}" for e in causes])


if __name__ == "__main__":
Expand Down
Loading