mirror of
https://github.com/nexu-io/open-design.git
synced 2026-09-20 06:15:06 +08:00
891981d460
* Optimize e2e tools-dev runtime parallelism * Remove visual networkidle wait * Optimize e2e vitest parallelism * Optimize Nix flake caching * Test CI on Blacksmith runners * Allow parallel manual CI runs * Tier CI runner sizes * Temporarily narrow CI debug scope * Instrument watcher CI timeouts * Instrument watcher event diagnostics * Avoid default polling in watcher tests * Skip runtime trace during watcher debug * Probe ARM runner tiers for CI * Focus CI runner probe on x64 browser * Probe browser workers by runner size * Probe Playwright file parallelism * Probe Playwright worker scaling on 8v * Reshape CI topology * Fix split E2E Vitest CI lane * Simplify daemon CI topology * Optimize Windows payload CI setup * Revert "Optimize Windows payload CI setup" This reverts commit5cbc48c0af. * Cache better-sqlite3 Nix binding separately * Revert "Cache better-sqlite3 Nix binding separately" This reverts commit0384e3787e. * Remove unused Nix cache setup from CI * Use Blacksmith ARM for lightweight CI jobs
48 lines
1.5 KiB
TypeScript
48 lines
1.5 KiB
TypeScript
import { createServer } from 'node:net';
|
|
|
|
import type { ToolsDevPortAllocation } from './types.ts';
|
|
|
|
export async function allocateToolsDevPorts(): Promise<ToolsDevPortAllocation> {
|
|
const [daemonPort, webPort] = await Promise.all([reserveFreePort(), reserveFreePort()]);
|
|
if (daemonPort.port === webPort.port) {
|
|
await Promise.all([daemonPort.release(), webPort.release()]);
|
|
return await allocateToolsDevPorts();
|
|
}
|
|
let released = false;
|
|
return {
|
|
daemonPort: daemonPort.port,
|
|
webPort: webPort.port,
|
|
async release() {
|
|
if (released) return;
|
|
released = true;
|
|
await Promise.all([daemonPort.release(), webPort.release()]);
|
|
},
|
|
};
|
|
}
|
|
|
|
async function reserveFreePort(): Promise<{ port: number; release: () => Promise<void> }> {
|
|
const server = createServer();
|
|
await new Promise<void>((resolveListen, rejectListen) => {
|
|
server.once('error', rejectListen);
|
|
server.listen(0, '127.0.0.1', () => resolveListen());
|
|
});
|
|
const address = server.address();
|
|
if (address == null || typeof address === 'string') {
|
|
await new Promise<void>((resolveClose, rejectClose) => {
|
|
server.close((error) => (error == null ? resolveClose() : rejectClose(error)));
|
|
});
|
|
throw new Error('failed to allocate a local TCP port');
|
|
}
|
|
let released = false;
|
|
return {
|
|
port: address.port,
|
|
async release() {
|
|
if (released) return;
|
|
released = true;
|
|
await new Promise<void>((resolveClose, rejectClose) => {
|
|
server.close((error) => (error == null ? resolveClose() : rejectClose(error)));
|
|
});
|
|
},
|
|
};
|
|
}
|