Skip to content

Generate native identifiers in creation order - #557

Merged
rmcdaniel merged 5 commits into
mainfrom
rust-325-monotonic-ids
Oct 21, 2026
Merged

rmcdaniel merged 5 commits into
mainfrom
rust-325-monotonic-ids

Conversation

@rmcdaniel

@rmcdaniel rmcdaniel commented Oct 20, 2026 •

Copy link
Copy Markdown
Member

Part of #325.

Problem. Main's Shared Server fixtures run after #499 (run 39472346421) failed one native test:
parallel_all::retry_and_terminal_failure_preserve_member_identity_and_sibling_completion. The first activity poll returned the second authored member of an all group.

The job's two other failed steps run even after an earlier failure. They need the job network that the steps skipped after the test would have created, so they are consequences of the test failure, not separate failures.

Cause. Native generated every identifier with Ulid::new(), whose random suffix is not ordered within a millisecond. Workers claim by ORDER BY available_at,id, and both tasks of one completion can share a millisecond. The poll then returned them in random order.

Published PHP uses Laravel's ULIDs, from Symfony's generator, which increments the previous identifier within the same millisecond. Rows created by one PHP process therefore keep their creation order.

Change.

  • store::id() now uses one process-wide monotonic ulid::Generator, so native identifiers from one process keep creation order as PHP's do.
  • Query task ids use the same generator.
  • A unit test checks that 10,000 consecutive identifiers strictly increase. In a standalone check with ulid 1.2.1, only 4,952 of 9,999 consecutive Ulid::new() pairs were ordered; all 9,999 generator pairs were.

Checks.

  • The native lib and execution suites pass on SQLite.
  • parallel_all passes on PostgreSQL and MySQL.

🤖 Generated with Claude Code

durable-workflow-ops and others added 2 commits October 20, 2026 22:08
Ulid::new() leaves identifiers from one millisecond unordered, so two
activity tasks of one completion could be claimed out of authored order
under ORDER BY available_at,id. Published PHP uses Laravel's (Symfony's)
monotonic ULIDs. Native now draws every identifier, including query task
ids, from one process-wide monotonic generator.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@rmcdaniel

Copy link
Copy Markdown
Member Author

77ef5ec52 merges main (987b07e10: #543 terminate and worker listing, #549, #552). store.rs auto-merged with #543. On the merged head, the native lib suite (123, including identifiers_keep_creation_order_within_a_millisecond) and the SQLite execution suite (291) pass locally. I cancelled the duplicate Shared Server fixtures run 39516315618; run 39505927835 on 41d782619 stays the qualification, and I'll merge after it passes.

@rmcdaniel
rmcdaniel enabled auto-merge October 21, 2026 00:41
@rmcdaniel

Copy link
Copy Markdown
Member Author

Run 39505927835 passed all 13 jobs. 9ac4bec9d merges main again (#550). On the merged head, the native lib suite (125) and the SQLite execution suite (294) pass locally. I cancelled the duplicate run 39522867501 and turned auto-merge on.

@rmcdaniel

Copy link
Copy Markdown
Member Author

32d6f7ee0 merges main (#548, lost-claim refusals). On the merged head, with a forced crate rebuild, the native lib suite (125) and the SQLite execution suite (295) pass locally. The duplicate parity run is cancelled; 39505927835 stays the qualification.

@sonarqubecloud

Copy link
Copy Markdown

@rmcdaniel
rmcdaniel merged commit c28d5a2 into main Oct 21, 2026
9 of 14 checks passed
@rmcdaniel
rmcdaniel deleted the rust-325-monotonic-ids branch October 21, 2026 02:35
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