summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAiden Cline <[email protected]>2026-04-10 19:59:33 -0500
committerGitHub <[email protected]>2026-04-10 19:59:33 -0500
commit96c1c0363d5c3ab5d5ef23bdd880b533f42fba14 (patch)
tree8107231898c4e89eeaf4f72adb859e7227ec64b0
parent33819932ec347c365d3a6c0636264020cc39b5c1 (diff)
downloadopencode-96c1c0363d5c3ab5d5ef23bdd880b533f42fba14.tar.gz
opencode-96c1c0363d5c3ab5d5ef23bdd880b533f42fba14.zip
chore: rm unnecessary test (now we use effect) and the test is flaky (#21959)
-rw-r--r--packages/opencode/test/memory/abort-leak.test.ts143
1 files changed, 0 insertions, 143 deletions
diff --git a/packages/opencode/test/memory/abort-leak.test.ts b/packages/opencode/test/memory/abort-leak.test.ts
deleted file mode 100644
index 2d0180783..000000000
--- a/packages/opencode/test/memory/abort-leak.test.ts
+++ /dev/null
@@ -1,143 +0,0 @@
-import { describe, test, expect } from "bun:test"
-import path from "path"
-import { Effect } from "effect"
-import { FetchHttpClient } from "effect/unstable/http"
-import { Instance } from "../../src/project/instance"
-import { WebFetchTool } from "../../src/tool/webfetch"
-import { SessionID, MessageID } from "../../src/session/schema"
-
-const projectRoot = path.join(__dirname, "../..")
-
-const ctx = {
- sessionID: SessionID.make("ses_test"),
- messageID: MessageID.make(""),
- callID: "",
- agent: "build",
- abort: new AbortController().signal,
- messages: [],
- metadata: () => {},
- ask: async () => {},
-}
-
-const MB = 1024 * 1024
-const ITERATIONS = 50
-
-const getHeapMB = () => {
- Bun.gc(true)
- return process.memoryUsage().heapUsed / MB
-}
-
-describe("memory: abort controller leak", () => {
- test("webfetch does not leak memory over many invocations", async () => {
- await Instance.provide({
- directory: projectRoot,
- fn: async () => {
- const tool = await WebFetchTool.pipe(
- Effect.flatMap((info) => Effect.promise(() => info.init())),
- Effect.provide(FetchHttpClient.layer),
- Effect.runPromise,
- )
-
- // Warm up
- await tool.execute({ url: "https://example.com", format: "text" }, ctx).catch(() => {})
-
- Bun.gc(true)
- const baseline = getHeapMB()
-
- // Run many fetches
- for (let i = 0; i < ITERATIONS; i++) {
- await tool.execute({ url: "https://example.com", format: "text" }, ctx).catch(() => {})
- }
-
- Bun.gc(true)
- const after = getHeapMB()
- const growth = after - baseline
-
- console.log(`Baseline: ${baseline.toFixed(2)} MB`)
- console.log(`After ${ITERATIONS} fetches: ${after.toFixed(2)} MB`)
- console.log(`Growth: ${growth.toFixed(2)} MB`)
-
- // Memory growth should be minimal - less than 1MB per 10 requests
- // With the old closure pattern, this would grow ~0.5MB per request
- expect(growth).toBeLessThan(ITERATIONS / 10)
- },
- })
- }, 60000)
-
- test("compare closure vs bind pattern directly", async () => {
- const ITERATIONS = 500
-
- // Test OLD pattern: arrow function closure
- // Store closures in a map keyed by content to force retention
- const closureMap = new Map<string, () => void>()
- const timers: Timer[] = []
- const controllers: AbortController[] = []
-
- Bun.gc(true)
- Bun.sleepSync(100)
- const baseline = getHeapMB()
-
- for (let i = 0; i < ITERATIONS; i++) {
- // Simulate large response body like webfetch would have
- const content = `${i}:${"x".repeat(50 * 1024)}` // 50KB unique per iteration
- const controller = new AbortController()
- controllers.push(controller)
-
- // OLD pattern - closure captures `content`
- const handler = () => {
- // Actually use content so it can't be optimized away
- if (content.length > 1000000000) controller.abort()
- }
- closureMap.set(content, handler)
- const timeoutId = setTimeout(handler, 30000)
- timers.push(timeoutId)
- }
-
- Bun.gc(true)
- Bun.sleepSync(100)
- const after = getHeapMB()
- const oldGrowth = after - baseline
-
- console.log(`OLD pattern (closure): ${oldGrowth.toFixed(2)} MB growth (${closureMap.size} closures)`)
-
- // Cleanup after measuring
- timers.forEach(clearTimeout)
- controllers.forEach((c) => c.abort())
- closureMap.clear()
-
- // Test NEW pattern: bind
- Bun.gc(true)
- Bun.sleepSync(100)
- const baseline2 = getHeapMB()
- const handlers2: (() => void)[] = []
- const timers2: Timer[] = []
- const controllers2: AbortController[] = []
-
- for (let i = 0; i < ITERATIONS; i++) {
- const _content = `${i}:${"x".repeat(50 * 1024)}` // 50KB - won't be captured
- const controller = new AbortController()
- controllers2.push(controller)
-
- // NEW pattern - bind doesn't capture surrounding scope
- const handler = controller.abort.bind(controller)
- handlers2.push(handler)
- const timeoutId = setTimeout(handler, 30000)
- timers2.push(timeoutId)
- }
-
- Bun.gc(true)
- Bun.sleepSync(100)
- const after2 = getHeapMB()
- const newGrowth = after2 - baseline2
-
- // Cleanup after measuring
- timers2.forEach(clearTimeout)
- controllers2.forEach((c) => c.abort())
- handlers2.length = 0
-
- console.log(`NEW pattern (bind): ${newGrowth.toFixed(2)} MB growth`)
- console.log(`Improvement: ${(oldGrowth - newGrowth).toFixed(2)} MB saved`)
-
- expect(newGrowth).toBeLessThanOrEqual(oldGrowth)
- })
-})