Skip to content

Nexus workflow operation cancellation for CHASM#9915

Merged
bergundy merged 14 commits intotemporalio:mainfrom
bergundy:nexus-cancelation-task-handlers
Apr 13, 2026
Merged

Nexus workflow operation cancellation for CHASM#9915
bergundy merged 14 commits intotemporalio:mainfrom
bergundy:nexus-cancelation-task-handlers

Conversation

@bergundy
Copy link
Copy Markdown
Member

What changed?

Full implementation of the cancellation path for workflow Nexus operations on CHASM.
Including:

  • State machine logic
  • Component logic
  • Workflow event handlers
  • Integration into workflows
  • Executors

I also ended up doing quite a bit of refactoring to reuse as much of the code as possible across the cancellation and invocation executors.
Also added missing test coverage for the invocation executors.

I tried to structure this into separate commits that make reviews easy but ended up with a lot of fixes in later commits that touched code in earlier commits. Best to review in one piece.

bergundy added 12 commits April 10, 2026 12:03
- Add ParentPtr mock support for testing (NewMockParentPtr)
- Add Operation ParentPtr to Cancellation component for parent access
- Improve cancellation state machine: set task Destination via event,
  move Attempt increment to scheduled transitions, track Failure on
  terminal states
- Add cancelArgs, loadArgs, saveResult to Cancellation component
- Add OnNexusOperationCancellationCompleted/Failed to OperationStore
- Add comprehensive cancellation state machine tests
- Rename invocationResult to startResult, move to start_result.go
- Move cancellationResult types to cancellation_result.go
- Remove extracted types from task_handler_helpers.go
- Add OnNexusOperationCancellationCompleted/Failed to Workflow component
  to record history events when cancellation succeeds or fails
- Simplify CancelRequestCompleted/Failed event handlers to use Get()
  instead of TryGet() (cancellation must be present)
- Replace fmt.Sprintf error construction with serviceerror formatting
  functions (NewInternalf, NewNotFoundf)
- Extract nexusTaskHandlerBase with shared methods (lookupEndpoint,
  buildCallbackURL, setupCallContext, recordCallOutcome, newInvocation)
- Add Cancel() to invocation interface with HTTP, system, and timeout
  implementations
- Refactor operationInvocationTaskHandler to embed nexusTaskHandlerBase
- Implement cancellationInvocationTaskHandler with full Validate/Execute
- Implement cancellationBackoffTaskHandler with Validate/Execute
- Use commonTaskHandlerOptions for backoff and timeout handlers
Extract invocation interface and implementations into invocation.go,
base handler and options into task_handler_base.go, and move
generateCallbackToken to operation_tasks.go.
@bergundy bergundy requested review from a team as code owners April 10, 2026 19:54
@bergundy bergundy changed the title Nexus cancelation task handlers Nexus workflow operation cancellation for CHASM Apr 10, 2026
@stephanos stephanos self-requested a review April 10, 2026 19:57
Copy link
Copy Markdown
Contributor

@stephanos stephanos left a comment

Choose a reason for hiding this comment

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

I didn't get through the tests yet; I'll do that async after merge.

if err != nil {
return fmt.Errorf("failed to construct invocation: %w", err)
}
startTime := args.currentTime
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

operationInvocationTaskHandler is using

	startTime := time.Now() // nolint:forbidigo // Time can be used for timing metrics.

here - should this, too?

}
// Cancellation must be present to deliver a cancel request.
cancellation := field.Get(ctx).Cancellation.Get(ctx)
return nexusoperation.TransitionCancellationFailed.Apply(cancellation, ctx, nexusoperation.EventCancellationFailed{})
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This seems to be missing the Failure field assignment.

RetryPolicy: input.retryPolicy(),
})
default:
return nil, serviceerror.NewInternalf("cannot save invocation result of type %T", r)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
return nil, serviceerror.NewInternalf("cannot save invocation result of type %T", r)
return nil, serviceerror.NewInternalf("cannot save cancellation result of type %T", r)

if errors.Is(callErr, errOpProcessorFailed) {
return "operation-processor-failed"
}
var opTimeoutBelowMinErr *operationTimeoutBelowMinError
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We could use `errors.AsType in this method instead.

}
if args.scheduleToCloseTimeout > 0 {
callTimeout = min(callTimeout, args.scheduleToCloseTimeout-args.currentTime.Sub(args.scheduledTime))
timeoutType = enumspb.TIMEOUT_TYPE_SCHEDULE_TO_CLOSE
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

callTimeout and timeoutType are always overwritten when both timeouts are set?

Comment thread chasm/lib/workflow/workflow.go Outdated
e.WorkerMayIgnore = true // For compatibility with older SDKs.
})
return err

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: empty line

Comment thread chasm/lib/workflow/workflow.go Outdated
e.WorkerMayIgnore = true // For compatibility with older SDKs.
})
return err

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: empty line

@bergundy bergundy force-pushed the nexus-cancelation-task-handlers branch from 0843c2c to 06c95df Compare April 13, 2026 16:04
@bergundy bergundy requested a review from stephanos April 13, 2026 17:10
@bergundy bergundy merged commit f9b2f6d into temporalio:main Apr 13, 2026
57 of 63 checks passed
@bergundy bergundy deleted the nexus-cancelation-task-handlers branch April 13, 2026 17:48
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