Skip to content

Add experimental typed Nexus workflow clients - #1660

Open
Quinn-With-Two-Ns wants to merge 4 commits into
mainfrom
nexus/01-workflow-clients
Open

Quinn-With-Two-Ns wants to merge 4 commits into
mainfrom
nexus/01-workflow-clients

Conversation

@Quinn-With-Two-Ns

@Quinn-With-Two-Ns Quinn-With-Two-Ns commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Add experimental, type-safe workflow Nexus clients using the draft Nexus SDK's service and operation markers.
  • Support ctx.nexus_client(...), typed execute/start, operation tokens, cancellation, and repeatable typed results.

Note

This PR depends on https://github.com/nexus-rpc/sdk-rust/pull/2 I am holding off merging and releasing that until we are good with the Rust implementation as well.


Note

Medium Risk
Touches workflow replay determinism (stricter Nexus service/operation checks) and introduces experimental cross-service call paths with a git-pinned draft Nexus SDK; failure encoding/decoding changes affect how workflow errors surface.

Overview
Adds experimental, compile-time typed Nexus calls from workflows behind the experimental feature, built on a pinned draft nexus-rpc SDK dependency.

Workflow code can use ctx.nexus_client(service, options) to get a NexusServiceClient with typed execute (start + wait for result) and start (returns NexusOperationHandle with operation_token, cancel, and repeatable typed result). Options cover timeouts, cancellation_type (non-optional enum, default wait-for-completion), optional cancellation tokens, and event groups; wire service/operation names come from the Nexus service definition.

NexusOperationError and NexusOperationDecodeHint extend failure conversion so start/complete failures keep Nexus metadata and distinguish failed vs cancelled vs timed-out resolutions when Core omits failure info.

Replay breaking change: histories now surface nondeterminism if a replayed Nexus schedule’s service or operation does not match the command that recorded it. Docs and integration tests cover sync/async Nexus flows, cancellation, and replay.

Reviewed by Cursor Bugbot for commit f46ba05. Bugbot is set up for automated code reviews on this repo. Configure here.

@Quinn-With-Two-Ns
Quinn-With-Two-Ns added this pull request to stack #1663 October 15, 2026 21:20
@Quinn-With-Two-Ns
Quinn-With-Two-Ns marked this pull request as ready for review October 15, 2026 21:37
@Quinn-With-Two-Ns
Quinn-With-Two-Ns requested a review from a team as a code owner October 15, 2026 21:37

@Sushisource Sushisource left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Overall looking good. Some de-llm-ification to do.

Comment thread crates/workflow/src/nexus.rs Outdated
Comment on lines +86 to +92
pub schedule_to_close_timeout: Option<Duration>,
/// Maximum time from scheduling until the handler starts or synchronously completes.
/// `None` or zero disables this timeout.
pub schedule_to_start_timeout: Option<Duration>,
/// Maximum time for an asynchronous operation to complete after starting.
/// Ignored for synchronous operations; `None` or zero disables this timeout.
pub start_to_close_timeout: Option<Duration>,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Are there no required timeouts for these?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

No, none are required

Comment thread crates/workflow/src/nexus.rs Outdated
Comment thread crates/workflow/src/nexus.rs Outdated
Comment thread crates/sdk/README.md Outdated
Comment thread crates/sdk/README.md
Comment on lines +330 to +331
Service definitions use the draft [Nexus Rust SDK](https://github.com/nexus-rpc/sdk-rust/pull/2).
Until that SDK is published, add the same pinned dependency used by this SDK:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is this supposed to be here still? Should get removed fast-follow at least?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yeah I haven't published the Nexus crate yet, will need to do that before I can merge this

Comment thread crates/sdk/README.md Outdated

@chris-olszewski chris-olszewski left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Just serializing this since I have interview so I probably won't get to more before EoD, but the failure converter story seems off to me. I'll poke at it a bit locally so I have actual suggestions (and since I made the initial mess).

pub enum NexusOperationError {
/// The Nexus operation failed, retaining its complete normalized failure.
#[error("Nexus operation failed: {}", .0.failure().message)]
Failed(#[source] Box<IncomingError>),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We should probably have a narrower variant here similar to other error types. Could we have something similar to ActivityFailureError but nexus flavored?

Comment thread crates/workflow/src/nexus.rs Outdated
Comment thread crates/workflow/src/nexus.rs
Comment on lines +246 to +247
.to_error(&context_data, failure, NoopDecodeHint)
.map(NexusOperationError::from)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Self: smells fishy

@chris-olszewski

Copy link
Copy Markdown
Member

Took longer than expected, but here's my suggested changes wrt the error types: #1689

Quinn-With-Two-Ns and others added 3 commits October 23, 2026 14:03
Co-authored-by: Spencer Judge <spencer@temporal.io>
Co-authored-by: Spencer Judge <spencer@temporal.io>

This branch has not been deployed

No deployments
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.

3 participants