Skip to content

fix(egg): fallback runtime diagnostic config#5933

Closed
killagu wants to merge 4 commits intonextfrom
agent/egg-dev/3f8f113e
Closed

fix(egg): fallback runtime diagnostic config#5933
killagu wants to merge 4 commits intonextfrom
agent/egg-dev/3f8f113e

Conversation

@killagu
Copy link
Copy Markdown
Contributor

@killagu killagu commented May 6, 2026

Summary

  • Fallback runtime diagnostic dumps to ${baseDir}/run when config.rundir is missing.
  • Reuse the same rundir fallback for application router dump output.
  • Default missing or invalid workerStartTimeout to the Egg 10 minute startup timeout.

Verification

  • pnpm exec vitest run packages/egg/test/egg.test.ts --testNamePattern "runtime diagnostics fallback config"
  • pnpm --filter egg typecheck
  • pnpm exec vitest run packages/egg/test/egg.test.ts

Multica issue: EGG-85

Summary by CodeRabbit

  • Bug Fixes
    • Improved runtime directory handling with automatic fallback and ensured creation when missing
    • Enhanced worker startup timeout handling with a sensible default and more robust timeout behavior
  • Tests
    • Added tests verifying diagnostic dumps are written to the runtime location and startup timeout behavior across edge cases

Copilot AI review requested due to automatic review settings May 6, 2026 10:05
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented May 6, 2026

Deploying egg-v3 with  Cloudflare Pages  Cloudflare Pages

Latest commit: 45e50f6
Status: ✅  Deploy successful!
Preview URL: https://0dfda575.egg-v3.pages.dev
Branch Preview URL: https://agent-egg-dev-3f8f113e.egg-v3.pages.dev

View logs

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 6, 2026

📝 Walkthrough

Walkthrough

Runtime directory resolution and worker-start timeout were centralized: added DEFAULT_WORKER_START_TIMEOUT, getRuntimeRundir(), and getWorkerStartTimeout(); dumpConfig/dumpTiming now ensure the runtime directory exists before writing; _setupTimeoutTimer uses the new timeout logic. Tests covering rundir fallback and timeout defaults were added.

Changes

Runtime directory and worker timeout

Layer / File(s) Summary
Core Constants & Helpers
packages/egg/src/lib/egg.ts
Added DEFAULT_WORKER_START_TIMEOUT = 10 * 60 * 1000. Added getRuntimeRundir() (returns config.rundir when set, else path.join(baseDir, 'run')) and getWorkerStartTimeout() (returns positive finite config.workerStartTimeout or default).
Behavioral Wiring
packages/egg/src/lib/egg.ts
Updated _setupTimeoutTimer() to compute startup timeout via getWorkerStartTimeout() and use that local value for the timer and its callback.
Filesystem Safety
packages/egg/src/lib/application.ts, packages/egg/src/lib/egg.ts
dumpConfig() and dumpTiming() now call getRuntimeRundir() and create the directory with fs.mkdirSync(rundir, { recursive: true }) before writing JSON files (router.json, application_config.json, application_timing_*.json).
Tests
packages/egg/test/egg.test.ts
Added "runtime diagnostics fallback config" suite: removes rundir to verify dumps are written to baseDir/run, and checks getWorkerStartTimeout() behavior for missing/invalid values (uses default 10 minutes) and a valid configured value.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • eggjs/egg#5325: touches worker start timeout defaults/config and may overlap with getWorkerStartTimeout/DEFAULT_WORKER_START_TIMEOUT changes.
  • eggjs/egg#5921: modifies runtime output directory behavior and may intersect with getRuntimeRundir() and rundir fallback logic.

Suggested reviewers

  • akitaSummer
  • jerryliang64

Poem

🐰 I hop where runtimes like to hide,
I make their folders safe inside,
Timeouts tuned to start the race,
Dumps fall neatly in their place,
A small rabbit leaves no stride.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding fallback behavior for runtime diagnostic config when config.rundir is missing, directing output to baseDir/run.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent/egg-dev/3f8f113e

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.

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 fallback logic for the rundir and workerStartTimeout configurations, ensuring diagnostic files are dumped to a default directory when not specified. It also updates directory creation to use recursive mode. The review feedback identifies several redundant fs.existsSync checks that can be simplified because fs.mkdirSync with recursive: true is idempotent. Additionally, one check in application.ts is noted as unnecessary as it is already performed by the base class.

Comment thread packages/egg/src/lib/application.ts Outdated
Comment on lines 206 to 209
if (!fs.existsSync(rundir)) {
fs.mkdirSync(rundir, { recursive: true });
}
const dumpRouterFile = path.join(rundir, 'router.json');
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.

medium

This directory creation logic is redundant because super.dumpConfig() (called at line 200) already ensures that rundir exists using the same logic. Additionally, fs.mkdirSync with { recursive: true } is idempotent, making the fs.existsSync check unnecessary.

      const dumpRouterFile = path.join(rundir, 'router.json');

Comment thread packages/egg/src/lib/egg.ts Outdated
Comment on lines 572 to 574
if (!fs.existsSync(rundir)) {
fs.mkdirSync(rundir);
fs.mkdirSync(rundir, { recursive: true });
}
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.

medium

The fs.existsSync check is redundant when using fs.mkdirSync with { recursive: true }, as it is idempotent and will not throw if the directory already exists. Simplifying this improves code clarity.

      fs.mkdirSync(rundir, { recursive: true });

Comment thread packages/egg/src/lib/egg.ts Outdated
Comment on lines +595 to +597
if (!fs.existsSync(rundir)) {
fs.mkdirSync(rundir, { recursive: true });
}
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.

medium

The fs.existsSync check is redundant here as well since fs.mkdirSync with { recursive: true } handles existence checks internally.

      fs.mkdirSync(rundir, { recursive: true });

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 current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/egg/src/lib/egg.ts`:
- Around line 679-683: The getWorkerStartTimeout method currently treats any
finite number (including 0 and negatives) from this.config.workerStartTimeout as
valid; change the validation in getWorkerStartTimeout to accept only positive
finite numbers (> 0) and otherwise return the default timeout value so
non-positive values fall back to default. Locate getWorkerStartTimeout and
update the check that inspects this.config.workerStartTimeout to require
workerStartTimeout > 0 (in addition to typeof === 'number' and Number.isFinite)
before returning it.
🪄 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: 6cbfd9df-2073-43b8-94e0-551cca2f06d6

📥 Commits

Reviewing files that changed from the base of the PR and between 0389f2d and 2f65d29.

📒 Files selected for processing (3)
  • packages/egg/src/lib/application.ts
  • packages/egg/src/lib/egg.ts
  • packages/egg/test/egg.test.ts

Comment thread packages/egg/src/lib/egg.ts
@codecov
Copy link
Copy Markdown

codecov Bot commented May 6, 2026

Codecov Report

❌ Patch coverage is 85.71429% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.19%. Comparing base (aca1168) to head (45e50f6).
⚠️ Report is 1 commits behind head on next.

Files with missing lines Patch % Lines
packages/egg/src/lib/egg.ts 84.21% 3 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             next    #5933   +/-   ##
=======================================
  Coverage   85.18%   85.19%           
=======================================
  Files         668      668           
  Lines       19284    19298   +14     
  Branches     3782     3783    +1     
=======================================
+ Hits        16428    16440   +12     
- Misses       2464     2466    +2     
  Partials      392      392           

☔ 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

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 improves Egg’s runtime diagnostics robustness by ensuring config/timing/router dumps still work when config.rundir is missing, and by defaulting workerStartTimeout when it’s missing/invalid.

Changes:

  • Add getRuntimeRundir() fallback and use it for dumpConfig(), dumpTiming(), and router dump output.
  • Default workerStartTimeout via a helper (getWorkerStartTimeout()) and use it for the startup timeout timer.
  • Add a Vitest coverage block validating the rundir fallback and timeout defaulting behavior.

Reviewed changes

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

File Description
packages/egg/src/lib/egg.ts Adds rundir/timeout fallback helpers and routes diagnostics/start-timeout logic through them
packages/egg/src/lib/application.ts Reuses runtime rundir fallback for router dump and ensures directory creation
packages/egg/test/egg.test.ts Adds tests covering missing rundir dump behavior and missing workerStartTimeout defaulting

Comment thread packages/egg/src/lib/egg.ts Outdated

private getWorkerStartTimeout(): number {
const workerStartTimeout = this.config.workerStartTimeout;
if (typeof workerStartTimeout === 'number' && Number.isFinite(workerStartTimeout)) {
Comment thread packages/egg/src/lib/egg.ts
Comment thread packages/egg/src/lib/egg.ts
Copilot AI review requested due to automatic review settings May 6, 2026 10:18
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/egg/test/egg.test.ts (1)

294-310: ⚡ Quick win

Avoid duplicating the default-timeout magic number; import the constant instead.

10 * 60 * 1000 is repeated four times here and is also defined as DEFAULT_WORKER_START_TIMEOUT in packages/egg/src/lib/egg.ts. If the default ever changes, this test will silently drift. Consider exporting the constant from egg.ts and importing it here so the test stays locked to the source of truth.

♻️ Suggested change

In packages/egg/src/lib/egg.ts:

-const DEFAULT_WORKER_START_TIMEOUT = 10 * 60 * 1000;
+export const DEFAULT_WORKER_START_TIMEOUT = 10 * 60 * 1000;

In this test file:

-import { createApp, cluster, getFilepath, type MockApplication } from './utils.ts';
+import { createApp, cluster, getFilepath, type MockApplication } from './utils.ts';
+import { DEFAULT_WORKER_START_TIMEOUT } from '../src/lib/egg.ts';
@@
-        Reflect.set(app.config, 'workerStartTimeout', undefined);
-        assert.equal((app as any).getWorkerStartTimeout(), 10 * 60 * 1000);
-        Reflect.set(app.config, 'workerStartTimeout', 0);
-        assert.equal((app as any).getWorkerStartTimeout(), 10 * 60 * 1000);
-        Reflect.set(app.config, 'workerStartTimeout', -1);
-        assert.equal((app as any).getWorkerStartTimeout(), 10 * 60 * 1000);
-        Reflect.set(app.config, 'workerStartTimeout', Number.POSITIVE_INFINITY);
-        assert.equal((app as any).getWorkerStartTimeout(), 10 * 60 * 1000);
+        Reflect.set(app.config, 'workerStartTimeout', undefined);
+        assert.equal((app as any).getWorkerStartTimeout(), DEFAULT_WORKER_START_TIMEOUT);
+        Reflect.set(app.config, 'workerStartTimeout', 0);
+        assert.equal((app as any).getWorkerStartTimeout(), DEFAULT_WORKER_START_TIMEOUT);
+        Reflect.set(app.config, 'workerStartTimeout', -1);
+        assert.equal((app as any).getWorkerStartTimeout(), DEFAULT_WORKER_START_TIMEOUT);
+        Reflect.set(app.config, 'workerStartTimeout', Number.POSITIVE_INFINITY);
+        assert.equal((app as any).getWorkerStartTimeout(), DEFAULT_WORKER_START_TIMEOUT);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/egg/test/egg.test.ts` around lines 294 - 310, The test duplicates
the default timeout literal (10 * 60 * 1000) instead of using the canonical
constant; import DEFAULT_WORKER_START_TIMEOUT from the module that defines it
(packages/egg/src/lib/egg.ts) and replace the four literal occurrences in the
test for getWorkerStartTimeout() with that constant so the test follows the
single source of truth (ensure the import name matches the export in egg.ts).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/egg/test/egg.test.ts`:
- Around line 294-310: The test duplicates the default timeout literal (10 * 60
* 1000) instead of using the canonical constant; import
DEFAULT_WORKER_START_TIMEOUT from the module that defines it
(packages/egg/src/lib/egg.ts) and replace the four literal occurrences in the
test for getWorkerStartTimeout() with that constant so the test follows the
single source of truth (ensure the import name matches the export in egg.ts).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2eee452f-ffe7-492f-a243-9ce8da06b24e

📥 Commits

Reviewing files that changed from the base of the PR and between 2f65d29 and 6d74bdd.

📒 Files selected for processing (3)
  • packages/egg/src/lib/application.ts
  • packages/egg/src/lib/egg.ts
  • packages/egg/test/egg.test.ts

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

cloudflare-workers-and-pages Bot commented May 6, 2026

Deploying egg with  Cloudflare Pages  Cloudflare Pages

Latest commit: 45e50f6
Status: ✅  Deploy successful!
Preview URL: https://fbd8cd6f.egg-cci.pages.dev
Branch Preview URL: https://agent-egg-dev-3f8f113e.egg-cci.pages.dev

View logs

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 2 comments.

Comment thread packages/egg/src/lib/egg.ts
Comment thread packages/egg/src/lib/application.ts
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/egg/src/lib/egg.ts (1)

569-587: 💤 Low value

rundir computed outside the try block — minor style inconsistency with dumpTiming

Line 570 resolves rundir before entering the try, while dumpTiming (lines 592–593) resolves it inside. Since getRuntimeRundir() is infallible this makes no functional difference, but moving line 570 inside the try would make the two methods consistent and mean any hypothetical future failure is also caught by the existing handler.

♻️ Proposed alignment
 dumpConfig(): void {
-  const rundir = this.getRuntimeRundir();
   try {
+    const rundir = this.getRuntimeRundir();
     fs.mkdirSync(rundir, { recursive: true });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/egg/src/lib/egg.ts` around lines 569 - 587, The variable rundir is
computed with getRuntimeRundir() before the try in dumpConfig(), causing a style
inconsistency with dumpTiming() and leaving a hypothetical failure uncaught; fix
by moving the call to getRuntimeRundir() and the rundir variable declaration
inside the existing try block in the dumpConfig() method (so all filesystem ops
and rundir resolution are covered), keeping the rest of the logic—writing
dumpFile and dumpMetaFile and the catch logging—unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/egg/src/lib/egg.ts`:
- Around line 569-587: The variable rundir is computed with getRuntimeRundir()
before the try in dumpConfig(), causing a style inconsistency with dumpTiming()
and leaving a hypothetical failure uncaught; fix by moving the call to
getRuntimeRundir() and the rundir variable declaration inside the existing try
block in the dumpConfig() method (so all filesystem ops and rundir resolution
are covered), keeping the rest of the logic—writing dumpFile and dumpMetaFile
and the catch logging—unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 60434787-d937-4fc3-bb53-cfb73adfa0aa

📥 Commits

Reviewing files that changed from the base of the PR and between 6d74bdd and 45e50f6.

📒 Files selected for processing (2)
  • packages/egg/src/lib/application.ts
  • packages/egg/src/lib/egg.ts

@killagu
Copy link
Copy Markdown
Contributor Author

killagu commented May 6, 2026

Closing this PR because the fallback approach masks the actual bundled-loader failure.

Root cause checked from source: Egg already defines config.rundir and config.workerStartTimeout in packages/egg/src/config/config.default.ts, so seeing them as undefined means the framework config load unit was not loaded. In the bundled worker path, Egg framework paths can collapse to the bundle output root / chunk path, so config.default from the Egg framework is skipped. The root fix is PR #5930, which preserves framework eggPaths and plugin path metadata through the startup manifest and patches generated worker framework paths at runtime.

This PR should not merge as-is; EGG-85 should depend on #5930 / EGG-80 and then re-check the startup logs without adding diagnostic fallbacks.

@killagu
Copy link
Copy Markdown
Contributor Author

killagu commented May 6, 2026

Closing in favor of the root loader-path fix in #5930. The undefined values come from Egg framework config not being loaded in the bundled worker, not from missing diagnostic fallbacks.

@killagu killagu closed this May 6, 2026
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