Using scope in fiber causes heap out of memory error
Hello, I am trying to have some code on the route to be executed when there is an error or the server terminated. But when I am adding scope to the handler, I get a heap out of memory error.
import { Runtime as NodeRuntime } from "@effect/platform-node"
import { Context, Effect, Layer, Runtime, Scope } from "effect"
import express from "express"
// Define Express as a service
interface Express {
readonly _: unique symbol
}
const Express = Context.Tag<Express, ReturnType<typeof express>>("@services/Express")
// Define a helper to define routes as layers
const Route = <R, E, A>(
method: "all" | "get" | "post" | "put" | "delete" | "patch" | "options" | "head",
path: string,
effect: (req: express.Request, res: express.Response) => Effect.Effect<R, E, A>
) =>
Layer.scopedDiscard(
Effect.gen(function*(_) {
const app = yield* _(Express)
const scope = yield* _(Scope.Scope)
const runFork = Runtime.runFork(yield* _(Effect.runtime<R>()))
app[method](path, (req, res) => {
// removing { scope } makes the handler run.
runFork(effect(req, res), { scope })
})
})
)
// Define the main route
const IndexRouteLive = Route(
"get",
"/",
(_, res) => Effect.sync(() => res.send("Hello World!"))
)
// Server Setup
const ServerLive = Layer.scopedDiscard(
Effect.gen(function*(_) {
const port = 3001
const app = yield* _(Express)
yield* _(
Effect.acquireRelease(
Effect.sync(() => app.listen(port, () => console.log(`Example app listening on port ${port}`))),
(server) => Effect.sync(() => server.close())
)
)
})
)
// Setting Up Express
const ExpressLive = Layer.sync(Express, () => express())
// Combine the layers
const AppLive = ServerLive.pipe(
Layer.provide(IndexRouteLive),
Layer.provide(ExpressLive)
)
// Run the program
NodeRuntime.runMain(Layer.launch(AppLive))import { Runtime as NodeRuntime } from "@effect/platform-node"
import { Context, Effect, Layer, Runtime, Scope } from "effect"
import express from "express"
// Define Express as a service
interface Express {
readonly _: unique symbol
}
const Express = Context.Tag<Express, ReturnType<typeof express>>("@services/Express")
// Define a helper to define routes as layers
const Route = <R, E, A>(
method: "all" | "get" | "post" | "put" | "delete" | "patch" | "options" | "head",
path: string,
effect: (req: express.Request, res: express.Response) => Effect.Effect<R, E, A>
) =>
Layer.scopedDiscard(
Effect.gen(function*(_) {
const app = yield* _(Express)
const scope = yield* _(Scope.Scope)
const runFork = Runtime.runFork(yield* _(Effect.runtime<R>()))
app[method](path, (req, res) => {
// removing { scope } makes the handler run.
runFork(effect(req, res), { scope })
})
})
)
// Define the main route
const IndexRouteLive = Route(
"get",
"/",
(_, res) => Effect.sync(() => res.send("Hello World!"))
)
// Server Setup
const ServerLive = Layer.scopedDiscard(
Effect.gen(function*(_) {
const port = 3001
const app = yield* _(Express)
yield* _(
Effect.acquireRelease(
Effect.sync(() => app.listen(port, () => console.log(`Example app listening on port ${port}`))),
(server) => Effect.sync(() => server.close())
)
)
})
)
// Setting Up Express
const ExpressLive = Layer.sync(Express, () => express())
// Combine the layers
const AppLive = ServerLive.pipe(
Layer.provide(IndexRouteLive),
Layer.provide(ExpressLive)
)
// Run the program
NodeRuntime.runMain(Layer.launch(AppLive))