mirror of
https://github.com/oven-sh/bun
synced 2026-02-14 12:51:54 +00:00
* init * WIP fix post data/refactor * make it compile again * more things * undo padding and continue + fix posting + update lshpack * re-add fixes * really simple tests + fixes * add aborted event * fix trailers * add getDefaultSettings, getPackedSettings and getUnpackedSettings * fix + fmt * fixes * fix enablePush o be boolean * fix sendTrailers * fmt * fix goaway, fix some error messages * oops * revert some changes * more reverts * WIP * get CMAKE building lspack + ping behavior * remove files that should not be added anymore * remove old out files * remove old file * fix header reduce * bunch of fixes * fix socket unref * fix abort signal, rebase and fmt * socket unref tests * oops re-add cmake * fix stream state * more tests and fixes * fixes and ping tests * lshpack in Dockerfile * just copy lshpack * oops * fix end * wantTrailers * encode/decode fixes + grpc * channel credentials test * rebase * support h2c * fix h2c * fix h2c connect event + h2c tests * 'copy ls-hpack * ls-hpack build sh * oops * changing CMake + Docker * add ps1 build for ls-hpack fix clean * optimizations + fixes * remove protect/unprotect from handlers * more consistent errors * fix error code * oops * add goaway tests * oops uncoment tests * better errors more tests * add broken priority frame * better memory leak, some fixes and less flask tests * zig update .Big -> .big * closer threshold + h2 fix * remove log * test should not be flask * increase timeout on leak memory test * windows build * less flasky * always 127.0.0.1 * [autofix.ci] apply automated fixes * remove .call and use primordials * apply socket fix * fix win-build * should properly mark inactive * postgres fix * increase deadline * test tests * high light deadline timeouts * event loop test * make memory leak test faster * use buffer on payload test * check for socket.data before use * reduce iterations to see if timeout on mac intel * fix assertions * avoid localhost and simplify things * refactor memory leak test * Update src/js/node/tls.js * fixes --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: cirospaciari <ciro.spaciai@gmail.com> Co-authored-by: Jarred Sumner <jarred@jarredsumner.com> Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
108 lines
3.1 KiB
JavaScript
108 lines
3.1 KiB
JavaScript
import { heapStats } from "bun:jsc";
|
|
import http2 from "http2";
|
|
import path from "path";
|
|
function getHeapStats() {
|
|
return heapStats().objectTypeCounts;
|
|
}
|
|
|
|
const nodeExecutable = Bun.which("node");
|
|
if (!nodeExecutable) {
|
|
console.log("No node executable found");
|
|
process.exit(99); // 99 no node executable
|
|
}
|
|
async function nodeEchoServer() {
|
|
const subprocess = Bun.spawn([nodeExecutable, path.join(import.meta.dir, "node-echo-server.fixture.js")], {
|
|
stdout: "pipe",
|
|
});
|
|
const reader = subprocess.stdout.getReader();
|
|
const data = await reader.read();
|
|
const decoder = new TextDecoder("utf-8");
|
|
const address = JSON.parse(decoder.decode(data.value));
|
|
const url = `https://${address.family === "IPv6" ? `[${address.address}]` : address.address}:${address.port}`;
|
|
return { address, url, subprocess };
|
|
}
|
|
// X iterations should be enough to detect a leak
|
|
const ITERATIONS = 50;
|
|
// lets send a bigish payload
|
|
const PAYLOAD = Buffer.from("a".repeat(128 * 1024));
|
|
|
|
const info = await nodeEchoServer();
|
|
|
|
async function runRequests(iterations) {
|
|
for (let j = 0; j < iterations; j++) {
|
|
let client = http2.connect(info.url, { rejectUnauthorized: false });
|
|
let promises = [];
|
|
// 100 multiplex POST connections per iteration
|
|
for (let i = 0; i < 100; i++) {
|
|
const { promise, resolve, reject } = Promise.withResolvers();
|
|
const req = client.request({ ":path": "/post", ":method": "POST" });
|
|
let got_response = false;
|
|
req.on("response", () => {
|
|
got_response = true;
|
|
});
|
|
|
|
req.setEncoding("utf8");
|
|
req.on("end", () => {
|
|
if (got_response) {
|
|
resolve();
|
|
} else {
|
|
reject(new Error("no response"));
|
|
}
|
|
});
|
|
req.write(PAYLOAD);
|
|
req.end();
|
|
promises.push(promise);
|
|
}
|
|
await Promise.all(promises);
|
|
client.close();
|
|
client = null;
|
|
promises = null;
|
|
Bun.gc(true);
|
|
}
|
|
}
|
|
|
|
try {
|
|
const startStats = getHeapStats();
|
|
|
|
// warm up
|
|
await runRequests(ITERATIONS);
|
|
await Bun.sleep(10);
|
|
Bun.gc(true);
|
|
// take a baseline
|
|
const baseline = process.memoryUsage.rss();
|
|
// run requests
|
|
await runRequests(ITERATIONS);
|
|
await Bun.sleep(10);
|
|
Bun.gc(true);
|
|
// take an end snapshot
|
|
const end = process.memoryUsage.rss();
|
|
|
|
const delta = end - baseline;
|
|
const bodiesLeaked = delta / PAYLOAD.length;
|
|
// we executed 10 requests per iteration
|
|
if (bodiesLeaked > ITERATIONS) {
|
|
console.log("Too many bodies leaked", bodiesLeaked);
|
|
process.exit(1);
|
|
}
|
|
|
|
const endStats = getHeapStats();
|
|
info.subprocess.kill();
|
|
// check for H2FrameParser leaks
|
|
const pendingH2Parsers = (endStats.H2FrameParser || 0) - (startStats.H2FrameParser || 0);
|
|
if (pendingH2Parsers > 5) {
|
|
console.log("Too many pending H2FrameParsers", pendingH2Parsers);
|
|
process.exit(pendingH2Parsers);
|
|
}
|
|
// check for TLSSocket leaks
|
|
const pendingTLSSockets = (endStats.TLSSocket || 0) - (startStats.TLSSocket || 0);
|
|
if (pendingTLSSockets > 5) {
|
|
console.log("Too many pending TLSSockets", pendingTLSSockets);
|
|
process.exit(pendingTLSSockets);
|
|
}
|
|
process.exit(0);
|
|
} catch (err) {
|
|
console.log(err);
|
|
info.subprocess.kill();
|
|
process.exit(99); // 99 exception
|
|
}
|