fix(web-next): cache bindAll promise for concurrent caller safety
Replace the boolean bound flag with a cached promise so concurrent callers (layout + page server components) await the same binding operation. Prevents DI resolution before containers are populated.
This commit is contained in:
@@ -28,7 +28,7 @@ import { bindDevSeedMarketingPages } from "@repo/marketing-pages/di/bind-dev-see
|
|||||||
import { bindDevSeedNavigation } from "@repo/navigation/di/bind-dev-seed";
|
import { bindDevSeedNavigation } from "@repo/navigation/di/bind-dev-seed";
|
||||||
import { bindDevSeedMedia } from "@repo/media/di/bind-dev-seed";
|
import { bindDevSeedMedia } from "@repo/media/di/bind-dev-seed";
|
||||||
|
|
||||||
let bound = false;
|
let bindPromise: Promise<void> | null = null;
|
||||||
|
|
||||||
// Shared container holds TRACER + LOGGER bindings; per-feature containers
|
// Shared container holds TRACER + LOGGER bindings; per-feature containers
|
||||||
// receive references via parameter passing. This separates the instrumentation
|
// receive references via parameter passing. This separates the instrumentation
|
||||||
@@ -87,8 +87,6 @@ function resolveJobsDevSeed(): { queue: IJobQueue } {
|
|||||||
* feature via `bindProductionX` exports.
|
* feature via `bindProductionX` exports.
|
||||||
*/
|
*/
|
||||||
export async function bindAllProduction(): Promise<void> {
|
export async function bindAllProduction(): Promise<void> {
|
||||||
if (bound) return;
|
|
||||||
bound = true;
|
|
||||||
const { tracer, logger } = resolveInstrumentation(); // Rule 0
|
const { tracer, logger } = resolveInstrumentation(); // Rule 0
|
||||||
const { queue } = await resolveJobsProduction();
|
const { queue } = await resolveJobsProduction();
|
||||||
const resolvedConfig = await config;
|
const resolvedConfig = await config;
|
||||||
@@ -114,8 +112,6 @@ export async function bindAllProduction(): Promise<void> {
|
|||||||
* Payload booted. Mutually exclusive with `bindAllProduction()`.
|
* Payload booted. Mutually exclusive with `bindAllProduction()`.
|
||||||
*/
|
*/
|
||||||
export async function bindAllDevSeed(): Promise<void> {
|
export async function bindAllDevSeed(): Promise<void> {
|
||||||
if (bound) return;
|
|
||||||
bound = true;
|
|
||||||
const { tracer, logger } = resolveInstrumentation(); // Rule 0
|
const { tracer, logger } = resolveInstrumentation(); // Rule 0
|
||||||
const { queue } = resolveJobsDevSeed();
|
const { queue } = resolveJobsDevSeed();
|
||||||
|
|
||||||
@@ -150,25 +146,25 @@ export async function bindAllDevSeed(): Promise<void> {
|
|||||||
* When @repo/core-realtime is scaffolded, extend to accept realtime deps
|
* When @repo/core-realtime is scaffolded, extend to accept realtime deps
|
||||||
* (IRealtimeBroadcaster, IRealtimeHandlerRegistry) and pass them through.
|
* (IRealtimeBroadcaster, IRealtimeHandlerRegistry) and pass them through.
|
||||||
*/
|
*/
|
||||||
export async function bindAll(): Promise<void> {
|
export function bindAll(): Promise<void> {
|
||||||
|
if (bindPromise) return bindPromise;
|
||||||
|
|
||||||
if (process.env.USE_DEV_SEED === "false") {
|
if (process.env.USE_DEV_SEED === "false") {
|
||||||
await bindAllProduction();
|
bindPromise = bindAllProduction();
|
||||||
return;
|
} else if (process.env.USE_DEV_SEED === "true") {
|
||||||
|
bindPromise = bindAllDevSeed();
|
||||||
|
} else if (process.env.NODE_ENV === "production") {
|
||||||
|
bindPromise = bindAllProduction();
|
||||||
|
} else {
|
||||||
|
bindPromise = bindAllDevSeed();
|
||||||
}
|
}
|
||||||
if (process.env.USE_DEV_SEED === "true") {
|
|
||||||
await bindAllDevSeed();
|
return bindPromise;
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (process.env.NODE_ENV === "production") {
|
|
||||||
await bindAllProduction();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await bindAllDevSeed();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Test-only resets — not exported via package. Used by bind-production.test.ts. */
|
/** Test-only resets — not exported via package. Used by bind-production.test.ts. */
|
||||||
export function __resetBindStateForTests(): void {
|
export function __resetBindStateForTests(): void {
|
||||||
bound = false;
|
bindPromise = null;
|
||||||
resolvedTracer = null;
|
resolvedTracer = null;
|
||||||
resolvedLogger = null;
|
resolvedLogger = null;
|
||||||
resolvedQueue = null;
|
resolvedQueue = null;
|
||||||
|
|||||||
Reference in New Issue
Block a user