-
Notifications
You must be signed in to change notification settings - Fork 104
Nexus: worker, workflow-backed operations, and workflow caller #813
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
base: main
Are you sure you want to change the base?
Conversation
a845a6f
to
7a121bb
Compare
862e4f9
to
8ac0192
Compare
8940d51
to
520aecf
Compare
2fc971f
to
8bd6011
Compare
5d54f48
to
8ddfb94
Compare
fa3e8ec
to
f7bf47b
Compare
@@ -94,6 +94,7 @@ informal introduction to the features and their implementation. | |||
- [Heartbeating and Cancellation](#heartbeating-and-cancellation) | |||
- [Worker Shutdown](#worker-shutdown) | |||
- [Testing](#testing-1) | |||
- [Nexus](#nexus) |
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 do not see this section
[tool.uv.sources] | ||
nexus-rpc = { path = "../nexus-sdk-python", editable = true } |
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.
Let's make sure not to merge until this is proper dependency
priority: temporalio.common.Priority = temporalio.common.Priority.default, | ||
# The following options are deliberately not exposed in overloads |
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.
Unresolved (but pedantic, don't have to take if not wanted, I am just afraid of users using them)
nexus_completion_callbacks: Sequence[NexusCompletionCallback] | ||
workflow_event_links: Sequence[temporalio.api.common.v1.Link.WorkflowEvent] | ||
request_id: Optional[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.
May want to mention here these are unstable/experimental
@@ -7231,6 +7260,17 @@ def api_key(self, value: Optional[str]) -> None: | |||
self.service_client.update_api_key(value) | |||
|
|||
|
|||
@dataclass(frozen=True) | |||
class NexusCompletionCallback: |
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 mention this is unstable/experimental and also not really for user use (I understand exposing because it's exposed in the interceptor)
temporalio/nexus/handler/_token.py
Outdated
if not all( | ||
c in "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-" | ||
for c in s | ||
): | ||
raise ValueError( | ||
"invalid base64URL encoded string: contains invalid characters" | ||
) |
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 and although not really documented well, I think urlsafe_b64decode
will fail on invalid chars (though can check there are no trailing =
if needed)
@@ -3,22 +3,27 @@ | |||
from __future__ import annotations |
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 in conflict with the statement on the PR description of "Feel free to ignore those files for now". Ignoring workflow caller stuff for now.
# TODO(nexus-prerelease): headers | ||
try: | ||
await self._handler.cancel_operation(ctx, request.operation_token) | ||
except Exception as err: |
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.
So this is the case where I think we should consider catching BaseException
. I think we need to swallow all user exceptions that can occur for any reason and respond back
try: | ||
await self._handler.cancel_operation(ctx, request.operation_token) | ||
except Exception as err: | ||
logger.exception("Failed to execute Nexus cancel operation method") |
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 had traditionally treated these types of things as "warning" level not "error" level because it is not an SDK error, it is a user-code error, the SDK is just fine.
try: | ||
await self._handler.cancel_operation(ctx, request.operation_token) | ||
except Exception as err: | ||
logger.exception("Failed to execute Nexus cancel operation method") |
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.
If possible, use the contextual logger that has the Nexus info on it for this and start exception
|
||
def __init__( | ||
self, | ||
start: Optional[ |
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.
Just for posterity, noting that I disagree with this approach vs a simple approach of instantiating this class with the start workflow args. I think making users do nested functions for something as simple as tying a workflow to an operation is rough.
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.
OK let's not treat that discussion as closed.
- Expose nexus.client(), nexus.info() - Don't expose contextvar
Accidentally broken at f8077c5
Initial Python Temporal Nexus implementation.
Temporal SDK PR to accompany
samples-python
PR Nexus samples samples-python#174Contains Nexus worker, components for users to define workflow-backed Nexus operations, and the ability to start and cancel a Nexus operation from a workflow.
Notes for reviewers
nexusrpc.handler.start_workflow
is a top-level static function, but currently there's still a public contextvar objectnexusrpc.handler.temporal_operation_context
. Let's settle on approach there. If we're using module-level getters I think they need to be named something likeget_client()
etc, despite the fact that we haveactivity.metric_meter()
? Little bit more discussion needed there.