Skip to content

fix(NODE-7575): reset ObjectId state when building startup snapshot#884

Open
addaleax wants to merge 1 commit intomongodb:mainfrom
addaleax:7575-dev
Open

fix(NODE-7575): reset ObjectId state when building startup snapshot#884
addaleax wants to merge 1 commit intomongodb:mainfrom
addaleax:7575-dev

Conversation

@addaleax
Copy link
Copy Markdown
Contributor

@addaleax addaleax commented May 6, 2026

Description

Summary of Changes

Use the relevant Node.js API to ensure that different processes indeed have different counter and process-unique values in their ObjectId classes, as intended, even when using Node.js's startup snapshot feature.

Notes for Reviewers

What is the motivation for this change?

Release Highlight

Release notes highlight

Double check the following

  • Lint is passing (npm run check:lint)
  • Self-review completed using the steps outlined here
  • PR title follows the correct format: type(NODE-xxxx)[!]: description
    • Example: feat(NODE-1234)!: rewriting everything in coffeescript
  • Changes are covered by tests
  • New TODOs have a related JIRA ticket

Copilot AI review requested due to automatic review settings May 6, 2026 14:10
@addaleax addaleax requested a review from a team as a code owner May 6, 2026 14:10
Comment thread src/objectid.ts
this.resetState();
// https://nodejs.org/api/v8.html#startup-snapshot-api
// @ts-expect-error Node.js types not present since this is an optional API
const { startupSnapshot } = globalThis?.process?.getBuiltinModule('v8') ?? {};
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.

Accessing the API this way was recommended here: nodejs/node#63138 (comment)

I would agree that this seems like a reasonable compromise

Comment thread src/objectid.ts

/** @internal */
private static resetState = (): void => {
this.index = Math.floor(Math.random() * 0x1000000);
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.

Drive-by fix: Math.random() never returns 1, and 0xffffff should be a valid counter value

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR addresses an ObjectId startup-snapshot regression by ensuring per-process ObjectId generation state (counter + process-unique bytes) is reinitialized when a Node.js startup snapshot is deserialized, and adds a regression test that validates ObjectId behavior across multiple snapshot runs.

Changes:

  • Add ObjectId static initialization logic that registers a V8 startup-snapshot deserialize callback to reset ObjectId per-process state.
  • Move PROCESS_UNIQUE into ObjectId static state and reset it alongside the counter seed.
  • Add a Node.js startup snapshot regression test that builds and runs a snapshot twice and compares generated ObjectIds.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/objectid.ts Adds ObjectId state reset + V8 startup snapshot deserialize callback wiring.
test/node/startup_snapshot.test.ts Adds regression coverage for ObjectId uniqueness across startup snapshot deserializations.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/objectid.ts
Comment on lines +83 to +88
// Less than 20 seconds between timestamps should be plenty of leeway
expect(Math.abs(parseInt(oid2.ts, 16) - parseInt(oid1.ts, 16))).to.be.lessThan(20);
// Distinct process unique values
expect(oid1.uniq).to.not.equal(oid2.uniq);
// Distinct counter values
expect(oid1.counter).to.not.equal(oid2.counter);
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, this is one in 16 million CI runs that fails, I can live with that

Use the relevant Node.js API to ensure that different processes
indeed have different counter and process-unique values in their
ObjectId classes, as intended, even when using Node.js's startup
snapshot feature.
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