Skip to content

Commit 66fe8dc

Browse files
Reflexclaude
andcommitted
style(loadtest): prettier-format raw-transport comparison scripts
The raw undici / node:http2 / node:https probes predated the repo's prettier/eslint style (double quotes), which fails `eslint .`. Format them so the rebased branch is lint-clean; no behavior change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 8602fbd commit 66fe8dc

7 files changed

Lines changed: 122 additions & 120 deletions

File tree

loadtest/alpn-check.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
import tls from "node:tls";
1+
import tls from 'node:tls';
22

3-
const BASE_URL = process.env.RUNLOOP_BASE_URL ?? "https://api.runloop.pro";
3+
const BASE_URL = process.env.RUNLOOP_BASE_URL ?? 'https://api.runloop.pro';
44
const url = new URL(BASE_URL);
55

66
console.log(`Checking ALPN for ${url.hostname}:${url.port || 443}`);
77

88
const socket = tls.connect(
99
{
1010
host: url.hostname,
11-
port: parseInt(url.port || "443", 10),
12-
ALPNProtocols: ["h2", "http/1.1"],
11+
port: parseInt(url.port || '443', 10),
12+
ALPNProtocols: ['h2', 'http/1.1'],
1313
servername: url.hostname,
1414
},
1515
() => {
@@ -19,6 +19,6 @@ const socket = tls.connect(
1919
},
2020
);
2121

22-
socket.on("error", (err) => {
23-
console.error("TLS error:", err.message);
22+
socket.on('error', (err) => {
23+
console.error('TLS error:', err.message);
2424
});

loadtest/h2-single-conn.ts

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,30 @@
1-
import http2 from "node:http2";
1+
import http2 from 'node:http2';
22

3-
const BASE_URL = process.env.RUNLOOP_BASE_URL ?? "https://api.runloop.pro";
3+
const BASE_URL = process.env.RUNLOOP_BASE_URL ?? 'https://api.runloop.pro';
44
const API_KEY = process.env.RUNLOOP_API_KEY!;
55

66
const body = JSON.stringify({
7-
blueprint_id: "bp_nonexistent_loadtest_00000",
8-
name: "loadtest-h2s-0",
9-
environment_variables: { TEST_VAR_1: "value_one" },
10-
launch_parameters: { resource_size_request: "SMALL" },
7+
blueprint_id: 'bp_nonexistent_loadtest_00000',
8+
name: 'loadtest-h2s-0',
9+
environment_variables: { TEST_VAR_1: 'value_one' },
10+
launch_parameters: { resource_size_request: 'SMALL' },
1111
});
1212

1313
function sendRequest(client: http2.ClientHttp2Session): Promise<{ latencyMs: number; status: number }> {
1414
return new Promise((resolve, reject) => {
1515
const start = performance.now();
1616
const req = client.request({
17-
":method": "POST",
18-
":path": "/v1/devboxes",
19-
"content-type": "application/json",
17+
':method': 'POST',
18+
':path': '/v1/devboxes',
19+
'content-type': 'application/json',
2020
authorization: `Bearer ${API_KEY}`,
2121
});
22-
req.on("response", (headers) => {
23-
const status = headers[":status"] as number;
24-
req.on("data", () => {});
25-
req.on("end", () => resolve({ latencyMs: performance.now() - start, status }));
22+
req.on('response', (headers) => {
23+
const status = headers[':status'] as number;
24+
req.on('data', () => {});
25+
req.on('end', () => resolve({ latencyMs: performance.now() - start, status }));
2626
});
27-
req.on("error", reject);
27+
req.on('error', reject);
2828
req.end(body);
2929
});
3030
}
@@ -33,8 +33,8 @@ async function main() {
3333
const url = new URL(BASE_URL);
3434
const client = http2.connect(url.origin);
3535
await new Promise<void>((resolve, reject) => {
36-
client.on("connect", resolve);
37-
client.on("error", reject);
36+
client.on('connect', resolve);
37+
client.on('error', reject);
3838
});
3939

4040
const maxStreams = client.remoteSettings?.maxConcurrentStreams;
@@ -53,9 +53,14 @@ async function main() {
5353

5454
const lats = results.map((r) => r.latencyMs).sort((a, b) => a - b);
5555
console.log(`${count} requests in ${wallMs.toFixed(0)}ms (${(count / (wallMs / 1000)).toFixed(1)} req/s)`);
56-
console.log(`Latency: min=${lats[0].toFixed(0)}ms p50=${lats[Math.floor(count / 2)].toFixed(0)}ms max=${lats[lats.length - 1].toFixed(0)}ms`);
56+
console.log(
57+
`Latency: min=${lats[0].toFixed(0)}ms p50=${lats[Math.floor(count / 2)].toFixed(0)}ms max=${lats[lats.length - 1].toFixed(0)}ms`,
58+
);
5759

5860
client.close();
5961
}
6062

61-
main().catch((e) => { console.error(e); process.exit(1); });
63+
main().catch((e) => {
64+
console.error(e);
65+
process.exit(1);
66+
});

loadtest/h2-test.ts

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
import http2 from "node:http2";
1+
import http2 from 'node:http2';
22

3-
const REQUEST_COUNT = parseInt(process.env.REQUEST_COUNT ?? "10000", 10);
4-
const NUM_CONNECTIONS = parseInt(process.env.NUM_CONNECTIONS ?? "10", 10);
5-
const BASE_URL = process.env.RUNLOOP_BASE_URL ?? "https://api.runloop.pro";
3+
const REQUEST_COUNT = parseInt(process.env.REQUEST_COUNT ?? '10000', 10);
4+
const NUM_CONNECTIONS = parseInt(process.env.NUM_CONNECTIONS ?? '10', 10);
5+
const BASE_URL = process.env.RUNLOOP_BASE_URL ?? 'https://api.runloop.pro';
66
const API_KEY = process.env.RUNLOOP_API_KEY!;
77

88
const body = JSON.stringify({
9-
blueprint_id: "bp_nonexistent_loadtest_00000",
10-
name: "loadtest-h2-0",
11-
environment_variables: { TEST_VAR_1: "value_one", TEST_VAR_2: "value_two" },
12-
metadata: { test_run: "h2", index: "0" },
13-
launch_parameters: { resource_size_request: "SMALL", keep_alive_time_seconds: 300 },
9+
blueprint_id: 'bp_nonexistent_loadtest_00000',
10+
name: 'loadtest-h2-0',
11+
environment_variables: { TEST_VAR_1: 'value_one', TEST_VAR_2: 'value_two' },
12+
metadata: { test_run: 'h2', index: '0' },
13+
launch_parameters: { resource_size_request: 'SMALL', keep_alive_time_seconds: 300 },
1414
});
1515

1616
function percentile(sorted: number[], p: number): number {
@@ -21,44 +21,38 @@ function percentile(sorted: number[], p: number): number {
2121
function connectH2(origin: string): Promise<http2.ClientHttp2Session> {
2222
return new Promise((resolve, reject) => {
2323
const client = http2.connect(origin);
24-
client.on("connect", () => resolve(client));
25-
client.on("error", reject);
24+
client.on('connect', () => resolve(client));
25+
client.on('error', reject);
2626
});
2727
}
2828

29-
function sendRequest(
30-
client: http2.ClientHttp2Session,
31-
): Promise<{ latencyMs: number; status: number }> {
29+
function sendRequest(client: http2.ClientHttp2Session): Promise<{ latencyMs: number; status: number }> {
3230
return new Promise((resolve, reject) => {
3331
const start = performance.now();
3432
const req = client.request({
35-
":method": "POST",
36-
":path": "/v1/devboxes",
37-
"content-type": "application/json",
33+
':method': 'POST',
34+
':path': '/v1/devboxes',
35+
'content-type': 'application/json',
3836
authorization: `Bearer ${API_KEY}`,
3937
});
40-
req.on("response", (headers) => {
41-
const status = headers[":status"] as number;
42-
req.on("data", () => {});
43-
req.on("end", () => resolve({ latencyMs: performance.now() - start, status }));
38+
req.on('response', (headers) => {
39+
const status = headers[':status'] as number;
40+
req.on('data', () => {});
41+
req.on('end', () => resolve({ latencyMs: performance.now() - start, status }));
4442
});
45-
req.on("error", reject);
43+
req.on('error', reject);
4644
req.end(body);
4745
});
4846
}
4947

5048
async function main() {
51-
console.log(
52-
`HTTP/2 test: ${REQUEST_COUNT} requests, ${NUM_CONNECTIONS} connections to ${BASE_URL}`,
53-
);
49+
console.log(`HTTP/2 test: ${REQUEST_COUNT} requests, ${NUM_CONNECTIONS} connections to ${BASE_URL}`);
5450

5551
const url = new URL(BASE_URL);
56-
const clients = await Promise.all(
57-
Array.from({ length: NUM_CONNECTIONS }, () => connectH2(url.origin)),
58-
);
52+
const clients = await Promise.all(Array.from({ length: NUM_CONNECTIONS }, () => connectH2(url.origin)));
5953

6054
const maxStreams = clients[0].remoteSettings?.maxConcurrentStreams;
61-
console.log(`Server MAX_CONCURRENT_STREAMS: ${maxStreams ?? "unknown"}`);
55+
console.log(`Server MAX_CONCURRENT_STREAMS: ${maxStreams ?? 'unknown'}`);
6256
console.log(`${NUM_CONNECTIONS} connections established\n`);
6357

6458
let completed = 0;

loadtest/raw-fetch-test.ts

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import https from "node:https";
1+
import https from 'node:https';
22

3-
const REQUEST_COUNT = parseInt(process.env.REQUEST_COUNT ?? "10000", 10);
4-
const BASE_URL = process.env.RUNLOOP_BASE_URL ?? "https://api.runloop.pro";
3+
const REQUEST_COUNT = parseInt(process.env.REQUEST_COUNT ?? '10000', 10);
4+
const BASE_URL = process.env.RUNLOOP_BASE_URL ?? 'https://api.runloop.pro';
55
const API_KEY = process.env.RUNLOOP_API_KEY!;
66

77
const agent = new https.Agent({
@@ -11,37 +11,35 @@ const agent = new https.Agent({
1111
});
1212

1313
const body = JSON.stringify({
14-
blueprint_id: "bp_nonexistent_loadtest_00000",
15-
name: "loadtest-raw-0",
16-
environment_variables: { TEST_VAR_1: "value_one", TEST_VAR_2: "value_two" },
17-
metadata: { test_run: "raw", index: "0" },
18-
launch_parameters: { resource_size_request: "SMALL", keep_alive_time_seconds: 300 },
14+
blueprint_id: 'bp_nonexistent_loadtest_00000',
15+
name: 'loadtest-raw-0',
16+
environment_variables: { TEST_VAR_1: 'value_one', TEST_VAR_2: 'value_two' },
17+
metadata: { test_run: 'raw', index: '0' },
18+
launch_parameters: { resource_size_request: 'SMALL', keep_alive_time_seconds: 300 },
1919
});
2020

2121
function makeRequest(index: number): Promise<{ latencyMs: number; status: number }> {
2222
const start = performance.now();
2323
return new Promise((resolve, reject) => {
24-
const url = new URL("/v1/devboxes", BASE_URL);
24+
const url = new URL('/v1/devboxes', BASE_URL);
2525
const req = https.request(
2626
url,
2727
{
28-
method: "POST",
28+
method: 'POST',
2929
agent,
3030
headers: {
31-
"content-type": "application/json",
31+
'content-type': 'application/json',
3232
authorization: `Bearer ${API_KEY}`,
33-
"content-length": Buffer.byteLength(body).toString(),
33+
'content-length': Buffer.byteLength(body).toString(),
3434
},
3535
},
3636
(res) => {
3737
res.resume();
38-
res.on("end", () =>
39-
resolve({ latencyMs: performance.now() - start, status: res.statusCode! }),
40-
);
41-
res.on("error", reject);
38+
res.on('end', () => resolve({ latencyMs: performance.now() - start, status: res.statusCode! }));
39+
res.on('error', reject);
4240
},
4341
);
44-
req.on("error", reject);
42+
req.on('error', reject);
4543
req.end(body);
4644
});
4745
}
@@ -55,9 +53,7 @@ async function main() {
5553
console.log(`Raw node:https test: ${REQUEST_COUNT} concurrent requests to ${BASE_URL}`);
5654

5755
const wallStart = performance.now();
58-
const results = await Promise.all(
59-
Array.from({ length: REQUEST_COUNT }, (_, i) => makeRequest(i)),
60-
);
56+
const results = await Promise.all(Array.from({ length: REQUEST_COUNT }, (_, i) => makeRequest(i)));
6157
const wallMs = performance.now() - wallStart;
6258

6359
const latencies = results.map((r) => r.latencyMs).sort((a, b) => a - b);

loadtest/undici-debug.ts

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
import { Agent, fetch } from "undici";
1+
import { Agent, fetch } from 'undici';
22

3-
const BASE_URL = process.env.RUNLOOP_BASE_URL ?? "https://api.runloop.pro";
3+
const BASE_URL = process.env.RUNLOOP_BASE_URL ?? 'https://api.runloop.pro';
44
const API_KEY = process.env.RUNLOOP_API_KEY!;
55

66
const body = JSON.stringify({
7-
blueprint_id: "bp_nonexistent_loadtest_00000",
8-
name: "loadtest-debug-0",
9-
environment_variables: { TEST_VAR_1: "value_one" },
10-
launch_parameters: { resource_size_request: "SMALL" },
7+
blueprint_id: 'bp_nonexistent_loadtest_00000',
8+
name: 'loadtest-debug-0',
9+
environment_variables: { TEST_VAR_1: 'value_one' },
10+
launch_parameters: { resource_size_request: 'SMALL' },
1111
});
1212

1313
async function main() {
14-
console.log("=== undici HTTP/2 debug ===\n");
14+
console.log('=== undici HTTP/2 debug ===\n');
1515

1616
const dispatcher = new Agent({
1717
allowH2: true,
@@ -24,31 +24,31 @@ async function main() {
2424

2525
// Single request to inspect protocol
2626
const res = await fetch(`${BASE_URL}/v1/devboxes`, {
27-
method: "POST",
27+
method: 'POST',
2828
headers: {
29-
"content-type": "application/json",
29+
'content-type': 'application/json',
3030
authorization: `Bearer ${API_KEY}`,
3131
},
3232
body,
3333
dispatcher,
3434
} as any);
3535

36-
console.log("Status:", res.status);
37-
console.log("HTTP version:", res.headers.get("x-http-version") ?? "(not reported)");
38-
console.log("\nResponse headers:");
36+
console.log('Status:', res.status);
37+
console.log('HTTP version:', res.headers.get('x-http-version') ?? '(not reported)');
38+
console.log('\nResponse headers:');
3939
for (const [k, v] of res.headers) {
4040
console.log(` ${k}: ${v}`);
4141
}
4242
await res.text();
4343

4444
// Quick 20-request burst to verify concurrency
45-
console.log("\n--- 20-request burst (2 connections, pipelining=10) ---");
45+
console.log('\n--- 20-request burst (2 connections, pipelining=10) ---');
4646
const wallStart = performance.now();
4747
const promises = Array.from({ length: 20 }, async () => {
4848
const start = performance.now();
4949
const r = await fetch(`${BASE_URL}/v1/devboxes`, {
50-
method: "POST",
51-
headers: { "content-type": "application/json", authorization: `Bearer ${API_KEY}` },
50+
method: 'POST',
51+
headers: { 'content-type': 'application/json', authorization: `Bearer ${API_KEY}` },
5252
body,
5353
dispatcher,
5454
} as any);

0 commit comments

Comments
 (0)