Skip to content

Commit 4d5c5fd

Browse files
killaguclaude
andcommitted
feat(core): add snapshot mode to lifecycle (stop after didLoad phase)
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>
1 parent a28abce commit 4d5c5fd

File tree

2 files changed

+18
-1
lines changed

2 files changed

+18
-1
lines changed

packages/core/src/egg.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ export interface EggCoreOptions {
3333
env?: string;
3434
/** Skip lifecycle hooks, only trigger loadMetadata for manifest generation */
3535
metadataOnly?: boolean;
36+
/**
37+
* When true, the application loads metadata only (plugins, configs, extensions,
38+
* services, controllers) without starting servers, timers, or connections.
39+
* Used for V8 startup snapshot construction.
40+
*/
41+
snapshot?: boolean;
3642
}
3743

3844
export type EggCoreInitOptions = Partial<EggCoreOptions>;
@@ -191,6 +197,7 @@ export class EggCore extends KoaApplication {
191197
baseDir: options.baseDir,
192198
app: this,
193199
logger: this.console,
200+
snapshot: options.snapshot,
194201
});
195202
this.lifecycle.on('error', (err) => this.emit('error', err));
196203
this.lifecycle.on('ready_timeout', (id) => this.emit('ready_timeout', id));

packages/core/src/lifecycle.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,12 @@ export interface LifecycleOptions {
6969
baseDir: string;
7070
app: EggCore;
7171
logger: EggConsoleLogger;
72+
/**
73+
* When true, the lifecycle stops after didLoad phase completes.
74+
* willReady, didReady, and serverDidReady hooks are NOT called.
75+
* Used for V8 startup snapshot construction.
76+
*/
77+
snapshot?: boolean;
7278
}
7379

7480
export type FunWithFullPath = Fun & { fullPath?: string };
@@ -119,7 +125,7 @@ export class Lifecycle extends EventEmitter {
119125
});
120126

121127
this.ready((err) => {
122-
if (!this.#metadataOnly) {
128+
if (!this.#metadataOnly && !this.options.snapshot) {
123129
void this.triggerDidReady(err);
124130
}
125131
debug('app ready');
@@ -372,6 +378,10 @@ export class Lifecycle extends EventEmitter {
372378
debug('trigger didLoad end');
373379
if (err) {
374380
this.ready(err);
381+
} else if (this.options.snapshot) {
382+
// In snapshot mode, stop after didLoad — skip willReady/didReady/serverDidReady
383+
debug('snapshot mode: skipping willReady, marking ready after didLoad');
384+
this.ready(true);
375385
} else {
376386
this.triggerWillReady();
377387
}

0 commit comments

Comments
 (0)