Bun/Elysia长请求接口触发无限循环问题求助
问题分析与解决方案
核心原因拆解
1. 浏览器(Chrome)的自动重试行为
Chrome针对长时间未响应的GET请求,存在隐性重试机制(触发阈值通常在10秒左右),当浏览器判定请求可能超时失败时,会自动重新发起请求,这就是你观察到"仅超时超过10秒才出现问题"的核心原因。
2. 代码的竞态条件漏洞
你使用的全局变量isProcessing存在竞态问题:当多个请求几乎同时进入接口时,第一个请求还未执行isProcessing = true,第二个请求就已完成if (isProcessing)的判断(此时值仍为false),导致多个请求同时进入处理逻辑,最终isProcessing状态被反复覆盖,无法正常重置,进而出现类似"无限循环"的异常。
针对性解决方案
修复竞态条件
用原子变量替代全局布尔值,确保状态判断与修改的原子性,比如使用Bun内置的AtomicBoolean:
import { AtomicBoolean } from 'bun'; const isProcessing = new AtomicBoolean(false); app.get("/test-long-request", async () => { const timeToWait = 20000; const startTime = DateTime.now(); // 原子性检查并锁定状态 if (!isProcessing.compareAndSet(false, true)) { console.error("Report generation is already in progress"); return new Response("Processing in progress", { status: 429 }); } try { await new Promise((r) => setTimeout(r, timeToWait)); return new Response( `[${startTime.toMillis()}] - Ok after ${timeToWait / 1000} seconds`, { status: 200 }, ); } finally { // 确保无论成功失败都重置状态 isProcessing.set(false); } });
抑制浏览器自动重试
- 修改请求方法:将GET改为POST,浏览器默认不会自动重试POST请求(除非明确配置);
- 添加响应头:在接口返回的响应中加入
Cache-Control: no-store, no-cache,告知浏览器不要缓存或重试该请求:return new Response( `[${startTime.toMillis()}] - Ok after ${timeToWait / 1000} seconds`, { status: 200, headers: { 'Cache-Control': 'no-store, no-cache' } }, ); - 关闭Chrome预测性加载:在Chrome设置中搜索"预测性网络操作",关闭"使用预测服务加载页面和提高性能"选项,排除浏览器预加载导致的重复请求。
排查Elysia是否存在问题
可以用纯Bun HTTP服务复现相同逻辑,验证是否是Elysia插件导致的问题:
import { serve } from 'bun'; import { DateTime } from 'luxon'; const isProcessing = new AtomicBoolean(false); serve({ fetch(req) { const url = new URL(req.url); if (url.pathname === '/test-long-request') { const timeToWait = 20000; const startTime = DateTime.now(); if (!isProcessing.compareAndSet(false, true)) { return new Response("Processing in progress", { status: 429 }); } return new Promise(resolve => { setTimeout(() => { isProcessing.set(false); resolve(new Response( `[${startTime.toMillis()}] - Ok after ${timeToWait / 1000} seconds`, { status: 200, headers: { 'Cache-Control': 'no-store' } } )); }, timeToWait); }); } return new Response('Not found', { status: 404 }); }, port: 3000, });
如果纯Bun服务没有重复请求问题,再排查Elysia的bearer/cors/staticPlugin插件是否有影响(比如CORS插件是否导致额外的OPTIONS请求被误判为业务请求)。
内容的提问来源于stack exchange,提问作者Foxlab
相关产品推荐
相关产品推荐

