Skip to content

Bound CHASM scheduler request IDs - #11240

Merged
chaptersix merged 7 commits into
temporalio:mainfrom
chaptersix:codex/bound-schedule-request-id
Jul 27, 2026
Merged

Bound CHASM scheduler request IDs#11240
chaptersix merged 7 commits into
temporalio:mainfrom
chaptersix:codex/bound-schedule-request-id

Conversation

@chaptersix

@chaptersix chaptersix commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Summary

Generate request IDs as sched-<auto|backfill-id>-<UUIDv5>. The UUID covers the namespace ID, schedule ID, conflict token, nominal time, and actual time.

This keeps generated IDs within the 255-byte SQL request-ID column while retaining the useful auto/backfill marker.

Validation

  • go test -tags test_dep ./chasm/lib/scheduler/...
  • make lint-code

@chaptersix
chaptersix force-pushed the codex/bound-schedule-request-id branch 2 times, most recently from 71e241e to afa4950 Compare July 23, 2026 19:20
@chaptersix
chaptersix marked this pull request as ready for review July 23, 2026 19:23
@chaptersix
chaptersix requested review from a team as code owners July 23, 2026 19:23

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 964f336470

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread common/schedules/id.go Outdated
@chaptersix
chaptersix force-pushed the codex/bound-schedule-request-id branch from 964f336 to f1903ae Compare July 23, 2026 19:41
@chaptersix
chaptersix marked this pull request as draft July 23, 2026 19:49
Comment thread common/schedules/id.go Outdated
@chaptersix
chaptersix force-pushed the codex/bound-schedule-request-id branch from f1903ae to 4999eb8 Compare July 23, 2026 20:10
@chaptersix chaptersix changed the title Bound generated scheduler request IDs Use UUIDv5 for scheduler request IDs Jul 24, 2026
@chaptersix
chaptersix marked this pull request as ready for review July 24, 2026 20:34
@chaptersix
chaptersix requested a review from a team as a code owner July 24, 2026 20:34

Copy link
Copy Markdown
Contributor Author

Why this request-ID representation change is safe:

  • A request ID is generated when a BufferedStart is created and is persisted with that entry. The invoker retries the stored value; it does not regenerate it.
  • Existing buffered starts therefore retain their current request IDs. The UUIDv5 representation applies only to actions buffered after this change is deployed.
  • UUIDv5 is deterministic: reprocessing the same logical action under the new code produces the same schedule-ID component, while the namespace, backfill ID, conflict token, and nominal/actual times continue to distinguish actions.
  • Generator and backfiller state advance together with buffered starts, so a completed action is not normally generated again across a rollout. If a task is retried before that state is committed, deterministic request IDs preserve idempotency.

The change is consequently a bounded representation change for future scheduler-generated IDs, not a rewrite of existing buffered state or a source of duplicate starts.

Comment thread chasm/lib/scheduler/internal/request_id.go Outdated
}

// Keep request IDs bounded and deterministic even when schedule IDs are long.
scheduleIDUUID := uuid.NewSHA1(uuid.Nil, []byte(scheduleID))

@davidporter-id-au davidporter-id-au Jul 24, 2026

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.

Not super sure I understand, wouldn't hashing the entire thing be the goal? What it if the NS is really long?

I am not sure if we need the requestID to be human-readable, but if we don't, then what about:

return uuid.NewSHA1(uuid.Nil, []byte(fmt.Sprintf(
		"sched-%s-%s-%s-%d-%d-%d",
		backfillID,
		namespaceID,
		scheduleID,
		conflictToken,
		nominal.UnixMilli(),
		actual.UnixMilli(),
	)))

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.

I think the only places we'd see this is in tdbg execution dumps of the chasms schedule or workflows started by a schedule.

I'd also like to keep auto vs backfiller id since the boolean marking a buffered start as manual is not displayed in tdbg output when false. Having the backfiller is also help with identifying which backfiller a buffered start came from.

@chaptersix chaptersix changed the title Use UUIDv5 for scheduler request IDs Bound CHASM scheduler request IDs Jul 27, 2026
return fmt.Sprintf(
"sched-%s-%s-%s-%d-%d-%d",
"sched-%s-%s",
backfillID,

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.

if you want to be completionist, it might be worth capping the backfill ID as well at a max length so that user-defined inputs can't exceed the field size.

@chaptersix
chaptersix merged commit 8cf4b81 into temporalio:main Jul 27, 2026
50 checks passed
davidporter-id-au added a commit to davidporter-id-au/temporal that referenced this pull request Jul 27, 2026
Resolves a conflict in addBackfiller from two overlapping changes:

- temporalio#11240 moved GenerateBackfillerID from common/schedules to
  chasm/lib/scheduler/internal, so the call site now uses
  schedulerinternal.GenerateBackfillerID.
- This branch removes the LastProcessedTime seeding from addBackfiller,
  which was the only timestamppb use in backfiller.go, so that import is
  dropped.

Both sides kept: the new import path plus the unseeded BackfillerState and
the comment explaining why the watermark must stay unset.

temporalio#11161 (generator buffer reserve) also landed in the meantime and reworks
allowedBufferedStarts, but leaves Execute's buffer-full early return intact
-- it still increments Attempt via defer without writing a watermark -- so
the premise of this fix is unchanged.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

2 participants