Asynchronous HTTP Handling with Effect Library and HttpRouter

Greetings.
I am trying to make asynchronous http handle in the Effect library using
HttpRouter
.
So that the server would accept and store requests, while handling them in the background, and send responses when they are ready.

I wonder, are there any ready-to-go solutions for that?
Tried to implement it using Queues and Fibers, but I assume that this way the requests will still be answered one-by-one.

Thank you in advance.

My attempt to solve it:
const router = HttpRouter.empty.pipe(
  HttpRouter.post("/submit", postSubmitHandler.pipe(Effect.provide(PostSubmitQueue.Default))),
);

const postSubmitHandler = Effect.gen(function* () {
  const postSubmitQueue = yield* PostSubmitQueue
  const params = yield* ParsedSearchParams;
  const txStringParam = params["id"];

  postSubmitQueue.put(txStringParam)
  const fiber = yield* postSubmitQueue.retrieve()
  return yield* Fiber.join(fiber)
}).pipe(
  Effect.catchAll((e) =>
    Effect.gen(function* () {
      return yield* HttpServerResponse.json(
        { error: `Something went wrong: ${e}` },
        { status: 400 },
      );
    }),
  ),
);

export class PostSubmitQueue extends Effect.Service<PostSubmitQueue>()(
  "PostSubmitQueue",
  {
    effect: Effect.gen(function* () {
      const localQueue = yield* Queue.unbounded<
        Effect.Effect<
          RuntimeFiber<HttpServerResponse.HttpServerResponse, HttpBodyError | Error>,
          never,
          SqlClient
        >
      >();

      const put = (data: string | string[]) =>
        localQueue.offer(Effect.fork(postSubmitHelper(data)));

      const retrieve = () => Effect.gen(function* () {
        const fiberEffect = yield* localQueue.take
        const fiber = yield* fiberEffect
        return fiber
      })

      return {
        put,
        retrieve,
      } as const;
    }),
  },
) {}

const postSubmitHelper = (txStringParam: string | string[]) => Effect.gen(function* () {
  // Attemt to submit to the database and return the `HttpResponse`
})
Was this page helpful?