mirror of
https://github.com/getpaseo/paseo.git
synced 2026-07-29 12:01:31 +00:00
chore(lint): reduce relay test no-await-in-loop warnings
Refactor while-loops and for-retry loops in e2e.test.ts and live-relay.e2e.test.ts into recursive poll/attempt helpers. Remaining 8 warnings in encrypted-channel.ts concern the custom Transport interface (on-handler slots, not DOM EventTarget) and a sequential send loop; both reflect deliberate runtime contracts.
This commit is contained in:
@@ -92,17 +92,48 @@ async function waitForServer(
|
||||
relayProcess: ChildProcess,
|
||||
timeout = 15000,
|
||||
): Promise<void> {
|
||||
const start = Date.now();
|
||||
while (Date.now() - start < timeout) {
|
||||
const deadline = Date.now() + timeout;
|
||||
async function poll(): Promise<void> {
|
||||
if (Date.now() >= deadline) {
|
||||
throw new Error(`Server did not start on port ${port} within ${timeout}ms`);
|
||||
}
|
||||
assertRelayStillRunning(relayProcess);
|
||||
try {
|
||||
await tryConnect(port);
|
||||
return;
|
||||
} catch {
|
||||
await sleep(100);
|
||||
return poll();
|
||||
}
|
||||
}
|
||||
throw new Error(`Server did not start on port ${port} within ${timeout}ms`);
|
||||
return poll();
|
||||
}
|
||||
|
||||
function probeRelayWebSocket(port: number): Promise<boolean> {
|
||||
const serverId = `probe-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
|
||||
const probeUrl = `ws://127.0.0.1:${port}/ws?serverId=${serverId}&role=server&v=2`;
|
||||
return new Promise<boolean>((resolve) => {
|
||||
const ws = new WebSocket(probeUrl);
|
||||
let settled = false;
|
||||
const settle = (value: boolean) => {
|
||||
if (settled) return;
|
||||
settled = true;
|
||||
resolve(value);
|
||||
};
|
||||
const timer = setTimeout(() => {
|
||||
ws.terminate();
|
||||
settle(false);
|
||||
}, 5000);
|
||||
ws.once("open", () => {
|
||||
clearTimeout(timer);
|
||||
ws.close(1000, "probe");
|
||||
settle(true);
|
||||
});
|
||||
ws.once("error", () => {
|
||||
clearTimeout(timer);
|
||||
settle(false);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function waitForRelayWebSocketReady(
|
||||
@@ -110,39 +141,28 @@ async function waitForRelayWebSocketReady(
|
||||
relayProcess: ChildProcess,
|
||||
timeout = 60000,
|
||||
): Promise<void> {
|
||||
const start = Date.now();
|
||||
while (Date.now() - start < timeout) {
|
||||
assertRelayStillRunning(relayProcess);
|
||||
const serverId = `probe-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
|
||||
const probeUrl = `ws://127.0.0.1:${port}/ws?serverId=${serverId}&role=server&v=2`;
|
||||
const opened = await new Promise<boolean>((resolve) => {
|
||||
const ws = new WebSocket(probeUrl);
|
||||
let settled = false;
|
||||
const settle = (value: boolean) => {
|
||||
if (settled) return;
|
||||
settled = true;
|
||||
resolve(value);
|
||||
};
|
||||
const timer = setTimeout(() => {
|
||||
ws.terminate();
|
||||
settle(false);
|
||||
}, 5000);
|
||||
ws.once("open", () => {
|
||||
clearTimeout(timer);
|
||||
ws.close(1000, "probe");
|
||||
settle(true);
|
||||
});
|
||||
ws.once("error", () => {
|
||||
clearTimeout(timer);
|
||||
settle(false);
|
||||
});
|
||||
});
|
||||
if (opened) {
|
||||
return;
|
||||
const deadline = Date.now() + timeout;
|
||||
async function poll(): Promise<void> {
|
||||
if (Date.now() >= deadline) {
|
||||
throw new Error(`Relay WebSocket endpoint not ready on port ${port} within ${timeout}ms`);
|
||||
}
|
||||
assertRelayStillRunning(relayProcess);
|
||||
const opened = await probeRelayWebSocket(port);
|
||||
if (opened) return;
|
||||
await sleep(250);
|
||||
return poll();
|
||||
}
|
||||
throw new Error(`Relay WebSocket endpoint not ready on port ${port} within ${timeout}ms`);
|
||||
return poll();
|
||||
}
|
||||
|
||||
async function waitForProcessExit(
|
||||
relayProcess: ChildProcess,
|
||||
deadline: number,
|
||||
): Promise<void> {
|
||||
if (relayProcess.exitCode !== null) return;
|
||||
if (Date.now() >= deadline) return;
|
||||
await sleep(50);
|
||||
return waitForProcessExit(relayProcess, deadline);
|
||||
}
|
||||
|
||||
async function stopRelayProcess(relayProcess: ChildProcess): Promise<void> {
|
||||
@@ -151,20 +171,14 @@ async function stopRelayProcess(relayProcess: ChildProcess): Promise<void> {
|
||||
}
|
||||
|
||||
relayProcess.kill("SIGTERM");
|
||||
const start = Date.now();
|
||||
while (relayProcess.exitCode === null && Date.now() - start < SHUTDOWN_TIMEOUT_MS) {
|
||||
await sleep(50);
|
||||
}
|
||||
await waitForProcessExit(relayProcess, Date.now() + SHUTDOWN_TIMEOUT_MS);
|
||||
|
||||
if (relayProcess.exitCode !== null) {
|
||||
return;
|
||||
}
|
||||
|
||||
relayProcess.kill("SIGKILL");
|
||||
const killStart = Date.now();
|
||||
while (relayProcess.exitCode === null && Date.now() - killStart < 2000) {
|
||||
await sleep(50);
|
||||
}
|
||||
await waitForProcessExit(relayProcess, Date.now() + 2000);
|
||||
|
||||
if (relayProcess.exitCode === null) {
|
||||
throw new Error("relay process did not exit after SIGTERM/SIGKILL");
|
||||
|
||||
@@ -15,18 +15,20 @@ async function withRetry<T>(
|
||||
fn: () => Promise<T>,
|
||||
options: { retries: number; delayMs: number },
|
||||
): Promise<T> {
|
||||
let lastError: unknown;
|
||||
for (let attempt = 0; attempt <= options.retries; attempt++) {
|
||||
async function attempt(attemptNumber: number, lastError: unknown): Promise<T> {
|
||||
if (attemptNumber > options.retries) {
|
||||
throw lastError instanceof Error ? lastError : new Error(String(lastError));
|
||||
}
|
||||
try {
|
||||
return await fn();
|
||||
} catch (error) {
|
||||
lastError = error;
|
||||
if (attempt < options.retries) {
|
||||
if (attemptNumber < options.retries) {
|
||||
await new Promise((r) => setTimeout(r, options.delayMs));
|
||||
}
|
||||
return attempt(attemptNumber + 1, error);
|
||||
}
|
||||
}
|
||||
throw lastError instanceof Error ? lastError : new Error(String(lastError));
|
||||
return attempt(0, null);
|
||||
}
|
||||
|
||||
function waitOpen(ws: WebSocket, label: string): Promise<void> {
|
||||
|
||||
Reference in New Issue
Block a user