/** # 脚本说明 * 节点侧清理:按 pool.json 清单对节点逐个 DELETE /profiles/:fp?force=true * (admin API 删除不清节点数据;本脚本只处理压测池内的指纹,不动合法 Profile)。 * 用法:bun node-wipe-stress.ts */ const fs = require("fs") as typeof import("fs"); const NODE = "http://127.0.0.1:3106"; const DATA = `${new URL(".", import.meta.url).pathname}data`; const NODE_KEY = /^NODE_KEY=(.*)$/m.exec(fs.readFileSync("/opt/serpmax/node/.env", "utf8"))?.[1]?.trim() ?? ""; const pool = (await Bun.file(`${DATA}/pool.json`).json()) as { fingerprint: string }[]; const fps = [...new Set(pool.map(p => p.fingerprint).filter(Boolean))]; console.log(`[wipe] 池内指纹 ${fps.length} 个`); let ok = 0, miss = 0, err = 0; const workers = 12; let cursor = 0; async function worker(): Promise { while (cursor < fps.length) { const i = cursor++; const fp = fps[i]; try { const res = await fetch(`${NODE}/profiles/${fp}?force=true`, { method: "DELETE", headers: { "x-node-key": NODE_KEY }, signal: AbortSignal.timeout(30000), }); if (res.ok) ok++; else if (res.status === 404) miss++; else { err++; if (err < 8) console.error(`[wipe] ${fp} -> ${res.status}`); } } catch { err++; } } } await Promise.all(Array.from({ length: workers }, () => worker())); console.log(`[wipe] ok=${ok} miss(本就不在)=${miss} err=${err}`); const left = Bun.spawnSync(["bash", "-c", "ls /opt/serpmax/node/data/profiles/ | wc -l"], { stdout: "pipe" }).stdout.toString().trim(); console.log(`[wipe] 节点目录剩余=${left}`);