You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 05:07:16