bunelysiajs

Bun / Elysia entrypoint infinite loop


I wrote this app with Elysia 1.1.19 & Bun 1.1.27 :

const app = new Elysia()
.use(bearer())
.use(cors())
.use(
  staticPlugin({
    assets: "static",
    prefix: "/static",
  }),
);

const isProcessing = false;

app.get("/test-long-request", async () => {
  const timeToWait = 20000;
  const startTime = DateTime.now();

  if (isProcessing) {
    // If we enter again in the entrypoint before the end of the process (20 sec)
    console.error("Report generation is already in progress");
  }
  isProcessing = true;

  // We wait for 20 seconds
  await new Promise((r) => setTimeout(r, timeToWait));
  isProcessing = false;

  // We send response
  return new Response(
    `[${startTime.toMillis()}] - Ok after ${timeToWait / 1000} seconds`,
    { status: 200 },
  );
});

I use these 3 plugins (Bearer, CORS, and StaticPlugin) for the actual process that is supposed to replace the timeout. I’m just mentioning them in case someone else has encountered the same issue. DateTime object comes from the luxon lib.

My problem is that when I validate the URL with the entry point (http://localhost:3000/test-long-request), the entry point is executed again BEFORE the process has finished (specifically, the 20-second timeout). This causes an infinite loop since the process never completes and the response is never sent.

The issue occurs when the timeout exceeds 10 seconds. I’m not sure if the problem is with my browser (Chrome v129.0.6668.101) re-executing the request or something wrong with Elysia.

Has anyone else faced a similar problem?


Solution

  • Elysia uses Bun.serve internally, and bun uses uWS internally which has default timeout of 10s as stated in the issue https://github.com/oven-sh/bun/issues/13392

    You can pass idleTimeout option like .listen({idleTimeout: 30}) but you might need to upgrade the bun version to use them.