Skip to content

Conversation

@gow
Copy link
Contributor

@gow gow commented Jan 21, 2026

What changed?

Migrated the cancellation operation state transitions.
Depends on #9082

Why?

Migrating Nexus from HSM to CHASM

How did you test it?

  • built
  • run locally and tested manually
  • covered by existing tests
  • added new unit test(s)
  • added new functional test(s)

Note

Implements the cancellation state machine in CHASM and enriches cancellation state data.

  • Adds transitions for CANCELLATION_STATUS_*: schedule, reschedule from backoff, retryable failure -> backoff (with computed delay), non-retryable failure -> failed, and success -> succeeded
  • Emits CancellationTask and CancellationBackoffTask with appropriate ScheduledTime and Attempt handling
  • Records requested_time, increments attempt, sets last_attempt_complete_time, stores last_attempt_failure, and manages next_attempt_schedule_time
  • Updates proto/v1/operation.proto and generated operation.pb.go to include new CancellationState fields (requested_time, attempt, last_attempt_complete_time, last_attempt_failure, next_attempt_schedule_time, requested_event_id)
  • Adds exhaustive unit tests validating transitions, state updates, backoff intervals, and allowed-from-state checks

Written by Cursor Bugbot for commit 1a8c936. This will update automatically on new commits. Configure here.

@gow gow requested review from a team as code owners January 21, 2026 02:51
Comment on lines 19 to 52
var transitionCancellationScheduled = chasm.NewTransition(
[]nexusoperationpb.CancellationStatus{nexusoperationpb.CANCELLATION_STATUS_UNSPECIFIED},
nexusoperationpb.CANCELLATION_STATUS_SCHEDULED,
func(c *Cancellation, ctx chasm.MutableContext, event EventCancellationScheduled) error {
return serviceerror.NewUnimplemented("unimplemented")
// Record when cancellation was requested
c.RequestedTime = timestamppb.New(event.Time)

// Emit a cancellation task
ctx.AddTask(c, chasm.TaskAttributes{}, &nexusoperationpb.CancellationTask{
Attempt: c.Attempt,
})

return nil
},
)

// EventCancellationRescheduled is triggered when cancellation is meant to be rescheduled after backing off from a
// previous attempt.
type EventCancellationRescheduled struct {
}

var transitionCancellationRescheduled = chasm.NewTransition(
[]nexusoperationpb.CancellationStatus{nexusoperationpb.CANCELLATION_STATUS_BACKING_OFF},
nexusoperationpb.CANCELLATION_STATUS_SCHEDULED,
func(c *Cancellation, ctx chasm.MutableContext, event EventCancellationRescheduled) error {
return serviceerror.NewUnimplemented("unimplemented")
// Clear the next attempt schedule time
c.NextAttemptScheduleTime = nil

// Emit a cancellation task for the retry
ctx.AddTask(c, chasm.TaskAttributes{}, &nexusoperationpb.CancellationTask{
Attempt: c.Attempt,
})

return nil
Copy link
Contributor Author

Choose a reason for hiding this comment

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

These 2 transitions are identical. Can we merge them into one transition definition? (since a transition takes multiple source states)? Would that be idiomatic chasm code?

Base automatically changed from cg/nexus/2-cancellation to nexus/hsm-to-chasm-migration January 21, 2026 23:24
@gow gow requested review from bergundy and stephanos January 22, 2026 02:55
@gow gow force-pushed the nexus/hsm-to-chasm-migration branch from 6443639 to 90e445e Compare January 22, 2026 02:58
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

c.LastAttemptFailure = event.Failure

// Terminal state - no tasks to emit
return nil
Copy link

Choose a reason for hiding this comment

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

Missing RequestedTime when transitioning from UNSPECIFIED to FAILED

Medium Severity

The transitionCancellationFailed transition can occur from CANCELLATION_STATUS_UNSPECIFIED directly to CANCELLATION_STATUS_FAILED, but it never sets RequestedTime. In contrast, transitionCancellationScheduled (which also transitions from UNSPECIFIED) does set RequestedTime. According to the proto definition, RequestedTime represents "The time when cancellation was requested." When a cancellation immediately fails from UNSPECIFIED state, this field will remain nil, creating an inconsistency with the expected data model.

Fix in Cursor Fix in Web

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