@effect/platform-node 0.53.25 → 0.54.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,51 +1,55 @@
1
1
  import { WorkerError } from "@effect/platform/WorkerError"
2
2
  import * as Runner from "@effect/platform/WorkerRunner"
3
- import * as Cause from "effect/Cause"
3
+ import * as Deferred from "effect/Deferred"
4
4
  import * as Effect from "effect/Effect"
5
+ import * as Exit from "effect/Exit"
6
+ import * as FiberId from "effect/FiberId"
7
+ import * as FiberSet from "effect/FiberSet"
5
8
  import * as Layer from "effect/Layer"
6
- import * as Queue from "effect/Queue"
7
- import * as Schedule from "effect/Schedule"
9
+ import * as Scope from "effect/Scope"
8
10
  import * as WorkerThreads from "node:worker_threads"
9
11
 
10
12
  const platformRunnerImpl = Runner.PlatformRunner.of({
11
13
  [Runner.PlatformRunnerTypeId]: Runner.PlatformRunnerTypeId,
12
- start<I, O>(shutdown: Effect.Effect<void>) {
13
- return Effect.gen(function*(_) {
14
+ start<I, O>() {
15
+ return Effect.gen(function*() {
14
16
  if (!WorkerThreads.parentPort) {
15
- return yield* _(new WorkerError({ reason: "spawn", error: new Error("not in worker") }))
17
+ return yield* new WorkerError({ reason: "spawn", cause: new Error("not in a worker thread") })
16
18
  }
17
19
  const port = WorkerThreads.parentPort
18
- const queue = yield* _(Queue.unbounded<readonly [portId: number, message: I]>())
19
- yield* _(
20
- Effect.async<never, WorkerError>((resume) => {
21
- port.on("message", (message: Runner.BackingRunner.Message<I>) => {
22
- if (message[0] === 0) {
23
- queue.unsafeOffer([0, message[1]])
24
- } else {
25
- Effect.runFork(shutdown)
26
- }
27
- })
28
- port.on("messageerror", (error) => {
29
- resume(new WorkerError({ reason: "decode", error }))
30
- })
31
- port.on("error", (error) => {
32
- resume(new WorkerError({ reason: "unknown", error }))
33
- })
34
- }),
35
- Effect.tapErrorCause((cause) => Cause.isInterruptedOnly(cause) ? Effect.void : Effect.logDebug(cause)),
36
- Effect.retry(Schedule.forever),
37
- Effect.annotateLogs({
38
- package: "@effect/platform-node",
39
- module: "WorkerRunner"
40
- }),
41
- Effect.interruptible,
42
- Effect.forkScoped
43
- )
44
20
  const send = (_portId: number, message: O, transfers?: ReadonlyArray<unknown>) =>
45
21
  Effect.sync(() => port.postMessage([1, message], transfers as any))
46
- // ready
47
- port.postMessage([0])
48
- return { queue, send }
22
+ const run = <A, E, R>(handler: (portId: number, message: I) => Effect.Effect<A, E, R>) =>
23
+ Effect.uninterruptibleMask((restore) =>
24
+ Scope.make().pipe(
25
+ Effect.bindTo("scope"),
26
+ Effect.bind("fiberSet", ({ scope }) => FiberSet.make<any, WorkerError | E>().pipe(Scope.extend(scope))),
27
+ Effect.bind("runFork", ({ fiberSet }) => FiberSet.runtime(fiberSet)<R>()),
28
+ Effect.tap(({ fiberSet, runFork }) => {
29
+ port.on("message", (message: Runner.BackingRunner.Message<I>) => {
30
+ if (message[0] === 0) {
31
+ runFork(restore(handler(0, message[1])))
32
+ } else {
33
+ Deferred.unsafeDone(fiberSet.deferred, Exit.interrupt(FiberId.none))
34
+ }
35
+ })
36
+ port.on("messageerror", (cause) => {
37
+ Deferred.unsafeDone(fiberSet.deferred, new WorkerError({ reason: "decode", cause }))
38
+ })
39
+ port.on("error", (cause) => {
40
+ Deferred.unsafeDone(fiberSet.deferred, new WorkerError({ reason: "unknown", cause }))
41
+ })
42
+ port.postMessage([0])
43
+ }),
44
+ Effect.flatMap(({ fiberSet, scope }) =>
45
+ restore(FiberSet.join(fiberSet) as Effect.Effect<never, E | WorkerError>).pipe(
46
+ Effect.ensuring(Scope.close(scope, Exit.void))
47
+ )
48
+ )
49
+ )
50
+ )
51
+
52
+ return { run, send }
49
53
  })
50
54
  }
51
55
  })