1import { assert, describe, it, vitest } from "@effect/vitest"
2
3describe("Effect keepAlive", { concurrent: false }, () => {
4 it("makeRunMain keeps process alive until completion", async () => {
5 const originalSetInterval = globalThis.setInterval
6 const originalClearInterval = globalThis.clearInterval
7 const running = {} as ReturnType<typeof globalThis.setInterval>
8 let started = 0
9 let stopped = 0
10 let stoppedHandle: ReturnType<typeof globalThis.setInterval> | undefined
11 ;(globalThis as any).setInterval = () => {
12 started++
13 return running
14 }
15 ;(globalThis as any).clearInterval = (interval: ReturnType<typeof globalThis.setInterval>) => {
16 stopped++
17 stoppedHandle = interval
18 }
19
20 try {
21 vitest.resetModules()
22 const { Effect, Runtime } = await import("effect")
23 await new Promise<void>((resolve) => {
24 const runMain = Runtime.makeRunMain(({ fiber, teardown }) => {
25 fiber.addObserver((exit) => {
26 teardown(exit, () => resolve())
27 })
28 })
29 runMain(Effect.void)
30 })
31 assert.strictEqual(started, 1)
32 assert.strictEqual(stopped, 1)
33 assert.strictEqual(stoppedHandle, running)
34 } finally {
35 ;(globalThis as any).setInterval = originalSetInterval
36 ;(globalThis as any).clearInterval = originalClearInterval
37 vitest.resetModules()
38 }
39 })
40
41 it("makeRunMain when setInterval is blocked", async () => {
42 const originalSetInterval = globalThis.setInterval
43 const originalClearInterval = globalThis.clearInterval
44 let attempts = 0
45 ;(globalThis as any).setInterval = () => {
46 attempts++
47 throw new Error("blocked")
48 }
49 ;(globalThis as any).clearInterval = () => {
50 throw new Error("blocked")
51 }
52
53 try {
54 vitest.resetModules()
55 const { Effect, Runtime } = await import("effect")
56 await new Promise<void>((resolve) => {
57 const runMain = Runtime.makeRunMain(({ fiber, teardown }) => {
58 fiber.addObserver((exit) => {
59 teardown(exit, () => resolve())
60 })
61 })
62 runMain(Effect.void)
63 })
64 assert.strictEqual(attempts, 1)
65 } finally {
66 ;(globalThis as any).setInterval = originalSetInterval
67 ;(globalThis as any).clearInterval = originalClearInterval
68 vitest.resetModules()
69 }
70 })
71})