Skip to content

feat(core): add snapshot mode to lifecycle (stop before configDidLoad phase)#5852

Open
killagu wants to merge 5 commits intonextfrom
feat/snapshot-core
Open

feat(core): add snapshot mode to lifecycle (stop before configDidLoad phase)#5852
killagu wants to merge 5 commits intonextfrom
feat/snapshot-core

Conversation

@killagu
Copy link
Copy Markdown
Contributor

@killagu killagu commented Mar 31, 2026

Summary

  • Add snapshot?: boolean option to EggCoreOptions and LifecycleOptions
  • In snapshot mode, lifecycle stops after didLoad phase — skips willReady/didReady/serverDidReady
  • Foundation for V8 snapshot construction: loads all metadata without creating runtime resources

This is PR2 of 6 in the V8 startup snapshot series. Independent, no dependencies.

Changes

  • packages/core/src/egg.ts — Add snapshot option, pass to lifecycle
  • packages/core/src/lifecycle.ts — Snapshot-aware ready logic (stop after didLoad)

Test plan

  • All 36 core test files pass (396 tests, 25 skipped)
  • oxlint --type-aware clean

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added a snapshot startup mode that marks the app ready immediately after initial configuration load and skips subsequent startup lifecycle phases.
  • Tests
    • Added tests validating snapshot behavior: which startup hooks run or are skipped, readiness timing in snapshot vs normal startup, and cleanup/close behavior.

Copilot AI review requested due to automatic review settings March 31, 2026 02:13
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 31, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds an optional snapshot?: boolean option to EggCoreOptions and LifecycleOptions; when enabled, lifecycle finalization is triggered immediately after configDidLoad (marking ready) and subsequent phases/hooks (didLoad, willReady, didReady, serverDidReady) are skipped.

Changes

Cohort / File(s) Summary
Core
packages/core/src/egg.ts
Add snapshot?: boolean to EggCoreOptions and forward snapshot: options.snapshot into the Lifecycle constructor.
Lifecycle
packages/core/src/lifecycle.ts
Add snapshot?: boolean to LifecycleOptions. After configDidLoad, if snapshot is true call this.ready(true) and return, skipping triggerDidLoad, triggerWillReady, triggerDidReady, and serverDidReady execution; also avoid calling triggerDidReady when metadataOnly or snapshot are true.
Tests
packages/core/test/snapshot.test.ts
New Vitest suite verifying snapshot mode: only configWillLoad/configDidLoad run, later lifecycle hooks are skipped, readiness occurs after configDidLoad, beforeClose still runs, and EggCore propagates snapshot option. Includes cleanup via afterEach.

Sequence Diagram(s)

(omitted)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • jerryliang64

Poem

🐰✨ I hop through configs, light and spry,
ConfigDidLoad done — then I sigh.
Snapshot whispers: "rest, be steady",
Skip the bustle; stay calm and ready.
A nibble, a nap, and carrot dreams 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Title check ⚠️ Warning The title claims to stop 'before configDidLoad phase' but the PR actually stops 'after configDidLoad phase', which contradicts the implementation described in the raw summary and pr_objectives. Update the title to 'feat(core): add snapshot mode to lifecycle (stop after configDidLoad phase)' to accurately reflect that snapshot mode halts after configDidLoad completes, not before it.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/snapshot-core

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 31, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 85.30%. Comparing base (a28abce) to head (3235abe).
⚠️ Report is 4 commits behind head on next.

Additional details and impacted files
@@            Coverage Diff             @@
##             next    #5852      +/-   ##
==========================================
- Coverage   88.37%   85.30%   -3.07%     
==========================================
  Files           9      666     +657     
  Lines          43    13214   +13171     
  Branches        8     1533    +1525     
==========================================
+ Hits           38    11272   +11234     
- Misses          5     1811    +1806     
- Partials        0      131     +131     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/core/src/egg.ts`:
- Around line 36-41: Update the snapshot option JSDoc to accurately reflect that
snapshot mode loads metadata and runs lifecycle hooks up to and including
didLoad, but stops before later phases (e.g., willReady/ready or starting
servers/timers/connections); specifically mention the snapshot?: boolean field
and reference the didLoad hook so authors know didLoad will execute while later
hooks and starting of servers/timers/connections will not.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d17e3b2d-04f9-4bc4-a675-93f15a46e55d

📥 Commits

Reviewing files that changed from the base of the PR and between 957c693 and af1e43d.

📒 Files selected for processing (2)
  • packages/core/src/egg.ts
  • packages/core/src/lifecycle.ts

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a snapshot option to the EggCore and Lifecycle classes to support V8 startup snapshot construction. When enabled, the application lifecycle stops after the didLoad phase, effectively skipping the willReady, didReady, and serverDidReady hooks to allow metadata loading without starting servers or connections. I have no feedback to provide.

Copy link
Copy Markdown
Contributor

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

Adds a new snapshot mode to @eggjs/core lifecycle execution, intended to support V8 startup snapshot construction by stopping the lifecycle after didLoad completes.

Changes:

  • Add snapshot?: boolean to EggCoreOptions and pass it into the Lifecycle constructor.
  • Add snapshot?: boolean to LifecycleOptions and alter lifecycle progression to mark ready after didLoad (skipping willReady and didReady in normal flow).

Reviewed changes

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

File Description
packages/core/src/lifecycle.ts Introduces snapshot option and stops lifecycle progression after didLoad by marking the app ready immediately.
packages/core/src/egg.ts Exposes snapshot option on EggCoreOptions and forwards it to Lifecycle.

Comment on lines +73 to +75
* When true, the lifecycle stops after didLoad phase completes.
* willReady, didReady, and serverDidReady hooks are NOT called.
* Used for V8 startup snapshot construction.
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

The JSDoc says serverDidReady hooks are NOT called in snapshot mode, but Lifecycle.triggerServerDidReady() can still be invoked externally (e.g. packages/egg/src/lib/egg.ts triggers it on egg-ready, and tests call it directly). To make this guarantee true, consider making triggerServerDidReady() a no-op when options.snapshot is true (or soften the comment to clarify it’s only skipped by the lifecycle’s normal flow).

Suggested change
* When true, the lifecycle stops after didLoad phase completes.
* willReady, didReady, and serverDidReady hooks are NOT called.
* Used for V8 startup snapshot construction.
* When true, the lifecycle's normal flow stops after the didLoad phase
* completes, and willReady, didReady, and serverDidReady hooks are not
* invoked automatically. External callers may still trigger those hooks
* manually if needed. Used for V8 startup snapshot construction.

Copilot uses AI. Check for mistakes.
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.

This is by design. The JSDoc documents what the lifecycle flow does automatically — it does not call serverDidReady. External callers invoking triggerServerDidReady() directly would be doing so intentionally and at their own risk.

Making it a no-op would prevent legitimate use cases where snapshot consumers need to selectively trigger later phases. The current wording ("hooks are NOT called") is accurate for the lifecycle's own behavior. Won't change, but appreciate the thoroughness.

Comment on lines +37 to +39
* When true, the application loads metadata only (plugins, configs, extensions,
* services, controllers) without starting servers, timers, or connections.
* Used for V8 startup snapshot construction.
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

The snapshot option comment here claims the app loads metadata only and avoids starting servers/timers/connections, but in this PR snapshot mode still runs the normal lifecycle through didLoad (including configWillLoad/configDidLoad, didLoad hooks, and registerBeforeStart tasks). That code can still start timers/connections. Please adjust the doc to match the actual semantics (stop after didLoad / skip ready phases), or enforce the stronger guarantee in code.

Suggested change
* When true, the application loads metadata only (plugins, configs, extensions,
* services, controllers) without starting servers, timers, or connections.
* Used for V8 startup snapshot construction.
* When true, the application runs a snapshot-oriented bootstrap for V8
* startup snapshot construction.
*
* In this mode Egg still executes the normal lifecycle up through `didLoad`,
* including `configWillLoad` / `configDidLoad`, `didLoad` hooks, and
* `registerBeforeStart` tasks, but stops before the ready / after-start
* phases (for example, it does not itself proceed to start HTTP servers).
*
* Code that runs in these earlier lifecycle stages (application or plugin
* hooks) may still create timers, background tasks, or external connections,
* so callers MUST NOT rely on this option to guarantee a completely
* side-effect-free or connection-free startup.

Copilot uses AI. Check for mistakes.
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.

The suggested 8-line JSDoc is too verbose for a simple boolean option. The key information developers need is: (1) lifecycle stops after didLoad, (2) later phases are skipped, (3) purpose is snapshot construction.

Will update to a concise version that accurately reflects the behavior without over-documenting edge cases that are better covered in framework docs. See reply to CodeRabbit's similar comment above.

Comment on lines 381 to 386
} else if (this.options.snapshot) {
// In snapshot mode, stop after didLoad — skip willReady/didReady/serverDidReady
debug('snapshot mode: skipping willReady, marking ready after didLoad');
this.ready(true);
} else {
this.triggerWillReady();
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

Snapshot-mode behavior (marking app ready after didLoad and skipping willReady/didReady) isn’t covered by tests in packages/core/test. Since this alters lifecycle semantics, please add a unit test that asserts the executed hook sequence in snapshot mode and verifies willReady/didReady are not invoked.

Copilot uses AI. Check for mistakes.
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.

Agree that tests are needed. Snapshot mode tests will be included in the integration test PR (feat/snapshot-scripts, PR #5853) which exercises the full snapshot build + restore flow end-to-end. Adding isolated lifecycle unit tests here would duplicate that coverage. The core change is minimal (3 lines of control flow) and well-understood.

Add `snapshot` option to EggCoreOptions and LifecycleOptions.
When enabled, lifecycle stops after didLoad phase completes,
skipping willReady, didReady, and serverDidReady hooks.
Used for V8 startup snapshot construction.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@killagu killagu force-pushed the feat/snapshot-core branch from af1e43d to 4d5c5fd Compare March 31, 2026 02:33
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages bot commented Mar 31, 2026

Deploying egg-v3 with  Cloudflare Pages  Cloudflare Pages

Latest commit: 3235abe
Status: ✅  Deploy successful!
Preview URL: https://6fa86685.egg-v3.pages.dev
Branch Preview URL: https://feat-snapshot-core.egg-v3.pages.dev

View logs

Update the snapshot option documentation to accurately describe that
lifecycle stops after didLoad phase, rather than the misleading
"loads metadata only" wording.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 31, 2026 02:38
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/core/src/lifecycle.ts (1)

72-77: Expose snapshot in StartEggOptions for API consistency.

EggCoreOptions now supports snapshot?: boolean, but callers of startEgg() cannot pass this option due to StartEggOptions not declaring it. Add snapshot?: boolean to StartEggOptions so the property flows through to the Application constructor without type safety loss.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/lifecycle.ts` around lines 72 - 77, Add the missing
snapshot property to StartEggOptions so callers can pass it through to startEgg;
specifically, update the StartEggOptions interface/type to include snapshot?:
boolean (matching EggCoreOptions), ensure startEgg accepts and forwards this
option into the Application constructor/new Application(...) call so the
Application receives snapshot, and keep the property name exactly snapshot to
preserve type compatibility with EggCoreOptions and Application.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/core/src/lifecycle.ts`:
- Around line 72-77: Add the missing snapshot property to StartEggOptions so
callers can pass it through to startEgg; specifically, update the
StartEggOptions interface/type to include snapshot?: boolean (matching
EggCoreOptions), ensure startEgg accepts and forwards this option into the
Application constructor/new Application(...) call so the Application receives
snapshot, and keep the property name exactly snapshot to preserve type
compatibility with EggCoreOptions and Application.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fa226234-7815-4523-a904-34c68ef734a6

📥 Commits

Reviewing files that changed from the base of the PR and between af1e43d and 4d5c5fd.

📒 Files selected for processing (2)
  • packages/core/src/egg.ts
  • packages/core/src/lifecycle.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/core/src/egg.ts

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages bot commented Mar 31, 2026

Deploying egg with  Cloudflare Pages  Cloudflare Pages

Latest commit: 3235abe
Status: ✅  Deploy successful!
Preview URL: https://7d1f71bd.egg-cci.pages.dev
Branch Preview URL: https://feat-snapshot-core.egg-cci.pages.dev

View logs

Verify that snapshot mode stops after didLoad and skips willReady/didReady/serverDidReady.
Also verify snapshot option propagation from EggCore to Lifecycle.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
packages/core/test/snapshot.test.ts (2)

96-116: Add serverDidReady positive-path coverage in normal mode.

Snapshot mode explicitly asserts serverDidReady is skipped, so it’s helpful to assert it runs when snapshot is not enabled.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/test/snapshot.test.ts` around lines 96 - 116, The test is
missing a positive-path assertion for the serverDidReady hook in normal mode;
after calling lifecycle.init(), lifecycle.triggerConfigWillLoad(), and await
lifecycle.ready(), add an assertion that callOrder includes 'serverDidReady'
(e.g., use assert.ok(callOrder.includes('serverDidReady'), 'serverDidReady
should be called in normal mode')) so the test verifies serverDidReady runs when
snapshot mode is not enabled; locate this near the existing assertions for
'willReady' and 'didReady' in the snapshot.test.ts lifecycle test.

120-142: Make this assertion snapshot-specific.

This test currently passes even in normal mode because only didLoad is instrumented. Consider asserting that no later hooks run in this case too.

Suggested tightening
-    it('should mark ready immediately after didLoad completes in snapshot mode', async () => {
-      let didLoadCompleted = false;
+    it('should mark ready immediately after didLoad completes in snapshot mode', async () => {
+      const callOrder: string[] = [];

       const lifecycle = new Lifecycle({
         baseDir: '.',
         app: new EggCore(),
         snapshot: true,
@@
       lifecycle.addBootHook(
         class Boot {
           async didLoad(): Promise<void> {
-            didLoadCompleted = true;
+            callOrder.push('didLoad');
+          }
+
+          async willReady(): Promise<void> {
+            callOrder.push('willReady');
+          }
+
+          async didReady(): Promise<void> {
+            callOrder.push('didReady');
           }
         },
       );
@@
-      assert.ok(didLoadCompleted, 'didLoad should have completed');
+      assert.deepEqual(callOrder, [ 'didLoad' ]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/test/snapshot.test.ts` around lines 120 - 142, The test must
verify snapshot-specific behavior by asserting that later lifecycle hooks do not
run in snapshot mode: in the test for Lifecycle with snapshot: true, add boolean
flags (e.g., willReadyRan = false, didReadyRan = false) and register a Boot hook
class implementing willReady() and didReady() that set those flags; after
lifecycle.init(); triggerConfigWillLoad(); await lifecycle.ready(); assert that
didLoadCompleted is true and also assert willReadyRan and didReadyRan are false
to ensure no later hooks ran in snapshot mode; reference the Lifecycle instance
and the Boot hook class used in the test to locate where to add these flags and
assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/core/test/snapshot.test.ts`:
- Around line 96-116: The test is missing a positive-path assertion for the
serverDidReady hook in normal mode; after calling lifecycle.init(),
lifecycle.triggerConfigWillLoad(), and await lifecycle.ready(), add an assertion
that callOrder includes 'serverDidReady' (e.g., use
assert.ok(callOrder.includes('serverDidReady'), 'serverDidReady should be called
in normal mode')) so the test verifies serverDidReady runs when snapshot mode is
not enabled; locate this near the existing assertions for 'willReady' and
'didReady' in the snapshot.test.ts lifecycle test.
- Around line 120-142: The test must verify snapshot-specific behavior by
asserting that later lifecycle hooks do not run in snapshot mode: in the test
for Lifecycle with snapshot: true, add boolean flags (e.g., willReadyRan =
false, didReadyRan = false) and register a Boot hook class implementing
willReady() and didReady() that set those flags; after lifecycle.init();
triggerConfigWillLoad(); await lifecycle.ready(); assert that didLoadCompleted
is true and also assert willReadyRan and didReadyRan are false to ensure no
later hooks ran in snapshot mode; reference the Lifecycle instance and the Boot
hook class used in the test to locate where to add these flags and assertions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d580e9f8-dee7-48b4-830a-fd5536fcd086

📥 Commits

Reviewing files that changed from the base of the PR and between f43d47c and b425d9b.

📒 Files selected for processing (1)
  • packages/core/test/snapshot.test.ts

Copy link
Copy Markdown
Contributor

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

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

After configDidLoad, SDKs begin initializing in didLoad hooks — opening
connections, starting timers, and creating resources that cannot survive
V8 heap serialization. Move the snapshot cutoff earlier: stop right after
configDidLoad completes, before triggerDidLoad() is called.

This captures all file loading, config merging, and prototype extensions
while avoiding non-serializable side effects. The deferred phases
(didLoad/willReady/didReady) will run at snapshot restore time instead.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@killagu killagu changed the title feat(core): add snapshot mode to lifecycle (stop after didLoad phase) feat(core): add snapshot mode to lifecycle (stop after configDidLoad phase) Mar 31, 2026
@killagu killagu changed the title feat(core): add snapshot mode to lifecycle (stop after configDidLoad phase) feat(core): add snapshot mode to lifecycle (stop before configDidLoad phase) Mar 31, 2026
…Load

The snapshot check was inside triggerConfigDidLoad(), running AFTER all
configDidLoad hooks had already executed. SDKs execute during configDidLoad
hooks, opening connections and starting timers which are not serializable
in V8 startup snapshots. Move the check into triggerConfigWillLoad() so
that configDidLoad is never called in snapshot mode.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 31, 2026 08:07
Copy link
Copy Markdown
Contributor

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

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

Comment on lines +72 to +79
/**
* When true, the lifecycle stops after configWillLoad phase completes.
* configDidLoad, didLoad, willReady, didReady, and serverDidReady hooks
* are NOT called. Used for V8 startup snapshot construction — SDKs
* typically execute during configDidLoad, opening connections and starting
* timers which are not serializable. The handling is analogous to
* metadataOnly mode: both short-circuit the lifecycle chain early.
*/
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

The PR description says snapshot mode “stops after didLoad”, but the implementation (and this JSDoc) now short-circuits immediately after configWillLoad (before configDidLoad). Please update the PR description (or rename/clarify the feature wording) so reviewers/users don’t get conflicting semantics.

Copilot uses AI. Check for mistakes.
* are NOT called. Used for V8 startup snapshot construction — SDKs
* typically execute during configDidLoad, opening connections and starting
* timers which are not serializable. The handling is analogous to
* metadataOnly mode: both short-circuit the lifecycle chain early.
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

In snapshot mode configDidLoad is skipped, which also means Boot.beforeClose() hooks are never registered (registration happens during triggerConfigDidLoad). The doc comment lists skipped startup hooks but doesn’t mention this shutdown implication; consider documenting that beforeClose hooks defined on boot classes won’t run automatically in snapshot mode (unless callers register close hooks manually).

Suggested change
* metadataOnly mode: both short-circuit the lifecycle chain early.
* metadataOnly mode: both short-circuit the lifecycle chain early.
*
* Note: because configDidLoad is skipped, Boot.beforeClose() hooks defined
* on boot classes (which are normally registered during triggerConfigDidLoad)
* are not registered and therefore will not run automatically in snapshot
* mode. If you need shutdown logic in snapshot mode, register close hooks
* manually on the application instance.

Copilot uses AI. Check for mistakes.
Comment on lines +39 to +41
* are skipped. Used for V8 startup snapshot construction — SDKs typically
* execute during `configDidLoad`, opening connections and starting timers
* which are not serializable. Analogous to `metadataOnly` mode.
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

Snapshot mode skips configDidLoad, which also prevents Boot.beforeClose() hooks from being registered (they’re registered during the configDidLoad loop). Since this option is public API on EggCoreOptions, consider mentioning this in the JSDoc so callers don’t assume app.close() will trigger boot-class beforeClose hooks in snapshot mode.

Suggested change
* are skipped. Used for V8 startup snapshot construction SDKs typically
* execute during `configDidLoad`, opening connections and starting timers
* which are not serializable. Analogous to `metadataOnly` mode.
* are skipped. Because `configDidLoad` is not run, Boot hooks registered
* there (including `beforeClose`) are never set up, and `app.close()` will
* therefore NOT invoke Boot `beforeClose` hooks in snapshot mode.
* Used for V8 startup snapshot construction SDKs typically execute during
* `configDidLoad`, opening connections and starting timers which are not
* serializable. Analogous to `metadataOnly` mode.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

@jerryliang64 jerryliang64 left a comment

Choose a reason for hiding this comment

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

LGTM

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