Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | 22x 22x 22x 22x 22x 22x 42x 42x 195x 195x 1x 1x 1x 1x 1x 31x 111x 111x | /**
* Compile Gatekeeper - Backward Compatibility Layer
*
* Delegates to UnifiedGatekeeper for centralized concurrency management.
* This maintains backward compatibility while using the new unified system internally.
*/
import { Logger } from "@shared/logger";
import { getUnifiedGatekeeper, TaskPriority } from "./unified-gatekeeper";
class CompileGatekeeper {
private readonly logger = new Logger("CompileGatekeeper");
private readonly maxConcurrent: number;
constructor(maxConcurrent?: number) {
// In worker threads, disable gatekeeper since the worker pool controls concurrency
const isWorkerThread = process.env.COMPILE_GATEKEEPER_DISABLED === "true";
// Allow explicit bypass via env var (for E2E test debugging)
const isDisabledViaEnv = process.env.DISABLE_COMPILE_GATEKEEPER === "true";
Iif (isWorkerThread || isDisabledViaEnv) {
this.maxConcurrent = Infinity;
this.logger.debug(
`CompileGatekeeper disabled - gatekeeper passes through immediately`,
);
} else {
this.maxConcurrent =
maxConcurrent || Number.parseInt(process.env.COMPILE_MAX_CONCURRENT || "4", 10);
this.logger.info(
`CompileGatekeeper initialized with max ${this.maxConcurrent} concurrent compiles`,
);
}
}
/**
* Acquire a compile slot with HIGH priority (for interactive simulations)
* Ensures user-initiated actions get prompt access
*/
async acquireHighPriority(): Promise<() => void> {
const unified = getUnifiedGatekeeper(this.maxConcurrent);
return await unified.acquireCompileSlotHighPriority("simulation-start");
}
/**
* Acquire a compile slot with NORMAL priority (backward compatibility)
* If no slots available, this returns a Promise that resolves when a slot becomes free.
*
* Usage:
* ```typescript
* const release = await gatekeeper.acquire();
* try {
* await compiler.compile(code);
* } finally {
* release();
* }
* ```
*/
async acquire(): Promise<() => void> {
const unified = getUnifiedGatekeeper(this.maxConcurrent);
return await unified.acquireCompileSlot(TaskPriority.NORMAL, 30000, "compile-gatekeeper");
}
/**
* Get current gatekeeper statistics for monitoring/debugging
*/
getStats() {
const unified = getUnifiedGatekeeper(this.maxConcurrent);
const unifiedStats = unified.getStats();
return {
maxConcurrent: unifiedStats.maxConcurrentCompiles,
available: unifiedStats.availableSlots,
active: unifiedStats.activeCompiles,
queued: unifiedStats.queuedCompiles,
};
}
/**
* Gracefully drain the queue and wait for all active compiles to finish.
* Useful for shutdown scenarios.
*/
async drain(): Promise<void> {
const unified = getUnifiedGatekeeper(this.maxConcurrent);
await unified.drain();
}
}
/**
* Global singleton instance
*/
let gatekeeperInstance: CompileGatekeeper | null = null;
export function getCompileGatekeeper(maxConcurrent?: number): CompileGatekeeper {
gatekeeperInstance ??= new CompileGatekeeper(maxConcurrent);
return gatekeeperInstance;
}
|