@effect/platform 0.37.0 → 0.37.2
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.
- package/dist/cjs/Transferable.js +70 -2
- package/dist/cjs/Transferable.js.map +1 -1
- package/dist/cjs/Worker.js.map +1 -1
- package/dist/cjs/WorkerRunner.js +11 -1
- package/dist/cjs/WorkerRunner.js.map +1 -1
- package/dist/cjs/internal/worker.js +51 -41
- package/dist/cjs/internal/worker.js.map +1 -1
- package/dist/cjs/internal/workerRunner.js +35 -15
- package/dist/cjs/internal/workerRunner.js.map +1 -1
- package/dist/dts/Transferable.d.ts +19 -0
- package/dist/dts/Transferable.d.ts.map +1 -1
- package/dist/dts/Worker.d.ts +5 -4
- package/dist/dts/Worker.d.ts.map +1 -1
- package/dist/dts/WorkerError.d.ts +2 -2
- package/dist/dts/WorkerError.d.ts.map +1 -1
- package/dist/dts/WorkerRunner.d.ts +22 -8
- package/dist/dts/WorkerRunner.d.ts.map +1 -1
- package/dist/esm/Transferable.js +41 -1
- package/dist/esm/Transferable.js.map +1 -1
- package/dist/esm/Worker.js.map +1 -1
- package/dist/esm/WorkerRunner.js +10 -0
- package/dist/esm/WorkerRunner.js.map +1 -1
- package/dist/esm/internal/worker.js +51 -41
- package/dist/esm/internal/worker.js.map +1 -1
- package/dist/esm/internal/workerRunner.js +32 -14
- package/dist/esm/internal/workerRunner.js.map +1 -1
- package/package.json +1 -1
- package/src/Transferable.ts +80 -2
- package/src/Worker.ts +6 -5
- package/src/WorkerError.ts +2 -2
- package/src/WorkerRunner.ts +41 -9
- package/src/internal/command.ts +1 -1
- package/src/internal/worker.ts +114 -83
- package/src/internal/workerRunner.ts +76 -19
package/src/internal/worker.ts
CHANGED
|
@@ -12,11 +12,13 @@ import { identity, pipe } from "effect/Function"
|
|
|
12
12
|
import * as Layer from "effect/Layer"
|
|
13
13
|
import * as Pool from "effect/Pool"
|
|
14
14
|
import * as Queue from "effect/Queue"
|
|
15
|
+
import * as ReadonlyArray from "effect/ReadonlyArray"
|
|
16
|
+
import * as Schedule from "effect/Schedule"
|
|
15
17
|
import type * as Scope from "effect/Scope"
|
|
16
18
|
import * as Stream from "effect/Stream"
|
|
17
19
|
import * as Transferable from "../Transferable.js"
|
|
18
20
|
import type * as Worker from "../Worker.js"
|
|
19
|
-
import
|
|
21
|
+
import { WorkerError } from "../WorkerError.js"
|
|
20
22
|
|
|
21
23
|
/** @internal */
|
|
22
24
|
export const defaultQueue = <I>() =>
|
|
@@ -55,22 +57,71 @@ export const makeManager = Effect.gen(function*(_) {
|
|
|
55
57
|
let idCounter = 0
|
|
56
58
|
return WorkerManager.of({
|
|
57
59
|
[WorkerManagerTypeId]: WorkerManagerTypeId,
|
|
58
|
-
spawn<I, E, O>({
|
|
60
|
+
spawn<I, E, O>({
|
|
61
|
+
encode,
|
|
62
|
+
initialMessage,
|
|
63
|
+
permits = 1,
|
|
64
|
+
queue,
|
|
65
|
+
spawn,
|
|
66
|
+
transfers = (_) => []
|
|
67
|
+
}: Worker.Worker.Options<I>) {
|
|
59
68
|
return Effect.gen(function*(_) {
|
|
60
69
|
const id = idCounter++
|
|
61
70
|
let requestIdCounter = 0
|
|
62
|
-
const readyLatch = yield* _(Deferred.make<never, void>())
|
|
63
71
|
const semaphore = yield* _(Effect.makeSemaphore(permits))
|
|
64
72
|
const requestMap = new Map<
|
|
65
73
|
number,
|
|
66
|
-
readonly [Queue.Queue<Exit.Exit<E | WorkerError, O
|
|
74
|
+
readonly [Queue.Queue<Exit.Exit<E | WorkerError, ReadonlyArray<O>>>, Deferred.Deferred<never, void>]
|
|
67
75
|
>()
|
|
76
|
+
const sendQueue = yield* _(Effect.acquireRelease(
|
|
77
|
+
Queue.unbounded<readonly [message: Worker.Worker.Request, transfers?: ReadonlyArray<unknown>]>(),
|
|
78
|
+
Queue.shutdown
|
|
79
|
+
))
|
|
68
80
|
|
|
69
81
|
const outbound = queue ?? (yield* _(defaultQueue<I>()))
|
|
70
82
|
yield* _(Effect.addFinalizer(() => outbound.shutdown))
|
|
71
83
|
|
|
72
|
-
|
|
73
|
-
|
|
84
|
+
yield* _(
|
|
85
|
+
Effect.gen(function*(_) {
|
|
86
|
+
const readyLatch = yield* _(Deferred.make<never, void>())
|
|
87
|
+
const backing = yield* _(
|
|
88
|
+
platform.spawn<Worker.Worker.Request, Worker.Worker.Response<E, O>>(spawn(id))
|
|
89
|
+
)
|
|
90
|
+
const send = pipe(
|
|
91
|
+
sendQueue.take,
|
|
92
|
+
Effect.flatMap(([message, transfers]) => backing.send(message, transfers)),
|
|
93
|
+
Effect.forever
|
|
94
|
+
)
|
|
95
|
+
const take = pipe(
|
|
96
|
+
Queue.take(backing.queue),
|
|
97
|
+
Effect.flatMap((msg) => {
|
|
98
|
+
if (msg[0] === 0) {
|
|
99
|
+
return Deferred.complete(readyLatch, Effect.unit)
|
|
100
|
+
}
|
|
101
|
+
return handleMessage(msg[1])
|
|
102
|
+
}),
|
|
103
|
+
Effect.forever
|
|
104
|
+
)
|
|
105
|
+
return yield* _(Effect.all([
|
|
106
|
+
Fiber.join(backing.fiber),
|
|
107
|
+
Effect.zipRight(Deferred.await(readyLatch), send),
|
|
108
|
+
take
|
|
109
|
+
], { concurrency: "unbounded" }))
|
|
110
|
+
}),
|
|
111
|
+
Effect.scoped,
|
|
112
|
+
Effect.onError((cause) =>
|
|
113
|
+
Effect.forEach(requestMap.values(), ([queue]) => Queue.offer(queue, Exit.failCause(cause)))
|
|
114
|
+
),
|
|
115
|
+
Effect.retry(
|
|
116
|
+
Schedule.exponential("250 millis").pipe(
|
|
117
|
+
Schedule.union(Schedule.spaced("30 seconds"))
|
|
118
|
+
)
|
|
119
|
+
),
|
|
120
|
+
Effect.annotateLogs({
|
|
121
|
+
package: "@effect/platform",
|
|
122
|
+
module: "Worker"
|
|
123
|
+
}),
|
|
124
|
+
Effect.forkScoped
|
|
74
125
|
)
|
|
75
126
|
|
|
76
127
|
yield* _(Effect.addFinalizer(() =>
|
|
@@ -82,42 +133,34 @@ export const makeManager = Effect.gen(function*(_) {
|
|
|
82
133
|
)
|
|
83
134
|
))
|
|
84
135
|
|
|
85
|
-
const handleMessage = (
|
|
136
|
+
const handleMessage = (response: Worker.Worker.Response<E, O>) =>
|
|
86
137
|
Effect.suspend(() => {
|
|
87
|
-
|
|
138
|
+
const queue = requestMap.get(response[0])
|
|
139
|
+
if (!queue) return Effect.unit
|
|
140
|
+
|
|
141
|
+
switch (response[1]) {
|
|
142
|
+
// data
|
|
88
143
|
case 0: {
|
|
89
|
-
return
|
|
144
|
+
return Queue.offer(queue[0], Exit.succeed(response[2]))
|
|
90
145
|
}
|
|
146
|
+
// end
|
|
91
147
|
case 1: {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
)
|
|
109
|
-
}
|
|
110
|
-
// error / defect
|
|
111
|
-
case 2:
|
|
112
|
-
case 3: {
|
|
113
|
-
return Queue.offer(
|
|
114
|
-
queue[0],
|
|
115
|
-
response[1] === 2
|
|
116
|
-
? Exit.fail(response[2])
|
|
117
|
-
: Exit.die(response[2])
|
|
118
|
-
)
|
|
119
|
-
}
|
|
120
|
-
}
|
|
148
|
+
return response.length === 2 ?
|
|
149
|
+
Queue.offer(queue[0], Exit.failCause(Cause.empty)) :
|
|
150
|
+
Effect.zipRight(
|
|
151
|
+
Queue.offer(queue[0], Exit.succeed(response[2])),
|
|
152
|
+
Queue.offer(queue[0], Exit.failCause(Cause.empty))
|
|
153
|
+
)
|
|
154
|
+
}
|
|
155
|
+
// error / defect
|
|
156
|
+
case 2:
|
|
157
|
+
case 3: {
|
|
158
|
+
return Queue.offer(
|
|
159
|
+
queue[0],
|
|
160
|
+
response[1] === 2
|
|
161
|
+
? Exit.fail(response[2])
|
|
162
|
+
: Exit.die(response[2])
|
|
163
|
+
)
|
|
121
164
|
}
|
|
122
165
|
}
|
|
123
166
|
})
|
|
@@ -126,7 +169,7 @@ export const makeManager = Effect.gen(function*(_) {
|
|
|
126
169
|
Effect.tap(
|
|
127
170
|
Effect.all([
|
|
128
171
|
Effect.sync(() => requestIdCounter++),
|
|
129
|
-
Queue.unbounded<Exit.Exit<E | WorkerError, O
|
|
172
|
+
Queue.unbounded<Exit.Exit<E | WorkerError, ReadonlyArray<O>>>(),
|
|
130
173
|
Deferred.make<never, void>()
|
|
131
174
|
]),
|
|
132
175
|
([id, queue, deferred]) =>
|
|
@@ -137,7 +180,11 @@ export const makeManager = Effect.gen(function*(_) {
|
|
|
137
180
|
)
|
|
138
181
|
|
|
139
182
|
const executeRelease = (
|
|
140
|
-
[id, , deferred]: [
|
|
183
|
+
[id, , deferred]: [
|
|
184
|
+
number,
|
|
185
|
+
Queue.Queue<Exit.Exit<E | WorkerError, ReadonlyArray<O>>>,
|
|
186
|
+
Deferred.Deferred<never, void>
|
|
187
|
+
],
|
|
141
188
|
exit: Exit.Exit<unknown, unknown>
|
|
142
189
|
) => {
|
|
143
190
|
const release = Effect.zipRight(
|
|
@@ -145,10 +192,7 @@ export const makeManager = Effect.gen(function*(_) {
|
|
|
145
192
|
Effect.sync(() => requestMap.delete(id))
|
|
146
193
|
)
|
|
147
194
|
return Exit.isInterrupted(exit) ?
|
|
148
|
-
Effect.zipRight(
|
|
149
|
-
Effect.ignore(backing.send([id, 1])),
|
|
150
|
-
release
|
|
151
|
-
) :
|
|
195
|
+
Effect.zipRight(sendQueue.offer([[id, 1]]), release) :
|
|
152
196
|
release
|
|
153
197
|
}
|
|
154
198
|
|
|
@@ -164,7 +208,7 @@ export const makeManager = Effect.gen(function*(_) {
|
|
|
164
208
|
Queue.take(queue),
|
|
165
209
|
Exit.match({
|
|
166
210
|
onFailure: (cause) => Cause.isEmpty(cause) ? Channel.unit : Channel.failCause(cause),
|
|
167
|
-
onSuccess: (value) => Channel.flatMap(Channel.write(Chunk.
|
|
211
|
+
onSuccess: (value) => Channel.flatMap(Channel.write(Chunk.unsafeFromArray(value)), () => loop)
|
|
168
212
|
})
|
|
169
213
|
)
|
|
170
214
|
return Stream.fromChannel(loop)
|
|
@@ -174,18 +218,11 @@ export const makeManager = Effect.gen(function*(_) {
|
|
|
174
218
|
const executeEffect = (request: I) =>
|
|
175
219
|
Effect.acquireUseRelease(
|
|
176
220
|
executeAcquire(request),
|
|
177
|
-
([, queue]) => Effect.
|
|
221
|
+
([, queue]) => Effect.flatMap(Queue.take(queue), Exit.map(ReadonlyArray.unsafeGet(0))),
|
|
178
222
|
executeRelease
|
|
179
223
|
)
|
|
180
224
|
|
|
181
|
-
|
|
182
|
-
Queue.take(backing.queue),
|
|
183
|
-
Effect.flatMap(handleMessage),
|
|
184
|
-
Effect.forever,
|
|
185
|
-
Effect.forkScoped
|
|
186
|
-
)
|
|
187
|
-
|
|
188
|
-
const postMessages = pipe(
|
|
225
|
+
yield* _(
|
|
189
226
|
semaphore.take(1),
|
|
190
227
|
Effect.zipRight(outbound.take),
|
|
191
228
|
Effect.flatMap(([id, request]) =>
|
|
@@ -194,35 +231,32 @@ export const makeManager = Effect.gen(function*(_) {
|
|
|
194
231
|
const result = requestMap.get(id)
|
|
195
232
|
if (!result) return Effect.unit
|
|
196
233
|
const transferables = transfers(request)
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
(cause) => Queue.offer(result[0], Exit.failCause(cause))
|
|
234
|
+
return pipe(
|
|
235
|
+
Effect.flatMap(
|
|
236
|
+
encode ? encode(request) : Effect.succeed(request),
|
|
237
|
+
(payload) => sendQueue.offer([[id, 0, payload], transferables])
|
|
202
238
|
),
|
|
203
|
-
|
|
239
|
+
Effect.catchAllCause((cause) => Queue.offer(result[0], Exit.failCause(cause))),
|
|
240
|
+
Effect.zipRight(Deferred.await(result[1]))
|
|
204
241
|
)
|
|
205
242
|
}),
|
|
206
243
|
Effect.ensuring(semaphore.release(1)),
|
|
207
244
|
Effect.fork
|
|
208
245
|
)
|
|
209
246
|
),
|
|
210
|
-
Effect.forever
|
|
211
|
-
)
|
|
212
|
-
|
|
213
|
-
const postMessagesFiber = yield* _(
|
|
214
|
-
Deferred.await(readyLatch),
|
|
215
|
-
Effect.zipRight(postMessages),
|
|
247
|
+
Effect.forever,
|
|
216
248
|
Effect.forkScoped
|
|
217
249
|
)
|
|
218
250
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
251
|
+
if (initialMessage) {
|
|
252
|
+
yield* _(
|
|
253
|
+
Effect.sync(initialMessage),
|
|
254
|
+
Effect.flatMap(executeEffect),
|
|
255
|
+
Effect.mapError((error) => WorkerError("spawn", error))
|
|
256
|
+
)
|
|
257
|
+
}
|
|
224
258
|
|
|
225
|
-
return { id,
|
|
259
|
+
return { id, execute, executeEffect }
|
|
226
260
|
}).pipe(Effect.parallelFinalizers)
|
|
227
261
|
}
|
|
228
262
|
})
|
|
@@ -303,6 +337,9 @@ export const makeSerialized = <
|
|
|
303
337
|
...options,
|
|
304
338
|
transfers(message) {
|
|
305
339
|
return Transferable.get(message)
|
|
340
|
+
},
|
|
341
|
+
encode(message) {
|
|
342
|
+
return Effect.mapError(Serializable.serialize(message), (error) => WorkerError("encode", error))
|
|
306
343
|
}
|
|
307
344
|
})
|
|
308
345
|
)
|
|
@@ -310,8 +347,7 @@ export const makeSerialized = <
|
|
|
310
347
|
const parseSuccess = Schema.decode(Serializable.successSchema(message as any))
|
|
311
348
|
const parseFailure = Schema.decode(Serializable.failureSchema(message as any))
|
|
312
349
|
return pipe(
|
|
313
|
-
|
|
314
|
-
Stream.flatMap((message) => backing.execute(message)),
|
|
350
|
+
backing.execute(message),
|
|
315
351
|
Stream.catchAll((error) => Effect.flatMap(parseFailure(error), Effect.fail)),
|
|
316
352
|
Stream.mapEffect(parseSuccess)
|
|
317
353
|
)
|
|
@@ -319,18 +355,13 @@ export const makeSerialized = <
|
|
|
319
355
|
const executeEffect = <Req extends I>(message: Req) => {
|
|
320
356
|
const parseSuccess = Schema.decode(Serializable.successSchema(message as any))
|
|
321
357
|
const parseFailure = Schema.decode(Serializable.failureSchema(message as any))
|
|
322
|
-
return
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
onFailure: (error) => Effect.flatMap(parseFailure(error), Effect.fail),
|
|
327
|
-
onSuccess: parseSuccess
|
|
328
|
-
})
|
|
329
|
-
)
|
|
358
|
+
return Effect.matchEffect(backing.executeEffect(message), {
|
|
359
|
+
onFailure: (error) => Effect.flatMap(parseFailure(error), Effect.fail),
|
|
360
|
+
onSuccess: parseSuccess
|
|
361
|
+
})
|
|
330
362
|
}
|
|
331
363
|
return identity<Worker.SerializedWorker<I>>({
|
|
332
364
|
id: backing.id,
|
|
333
|
-
join: backing.join,
|
|
334
365
|
execute: execute as any,
|
|
335
366
|
executeEffect: executeEffect as any
|
|
336
367
|
})
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import * as Schema from "@effect/schema/Schema"
|
|
2
2
|
import * as Serializable from "@effect/schema/Serializable"
|
|
3
3
|
import * as Cause from "effect/Cause"
|
|
4
|
+
import * as Chunk from "effect/Chunk"
|
|
4
5
|
import * as Context from "effect/Context"
|
|
5
6
|
import * as Effect from "effect/Effect"
|
|
6
7
|
import * as Either from "effect/Either"
|
|
7
8
|
import * as Fiber from "effect/Fiber"
|
|
8
9
|
import { pipe } from "effect/Function"
|
|
10
|
+
import * as Layer from "effect/Layer"
|
|
11
|
+
import * as Option from "effect/Option"
|
|
9
12
|
import * as Predicate from "effect/Predicate"
|
|
10
13
|
import * as Queue from "effect/Queue"
|
|
11
14
|
import type * as Scope from "effect/Scope"
|
|
@@ -28,14 +31,15 @@ export const PlatformRunner = Context.Tag<WorkerRunner.PlatformRunner>(
|
|
|
28
31
|
/** @internal */
|
|
29
32
|
export const make = <I, R, E, O>(
|
|
30
33
|
process: (request: I) => Stream.Stream<R, E, O> | Effect.Effect<R, E, O>,
|
|
31
|
-
options?: WorkerRunner.Runner.Options<O>
|
|
34
|
+
options?: WorkerRunner.Runner.Options<E, O>
|
|
32
35
|
) =>
|
|
33
36
|
Effect.gen(function*(_) {
|
|
34
37
|
const platform = yield* _(PlatformRunner)
|
|
35
38
|
const backing = yield* _(platform.start<Worker.Worker.Request<I>, Worker.Worker.Response<E>>())
|
|
36
39
|
const fiberMap = new Map<number, Fiber.Fiber<never, void>>()
|
|
40
|
+
const parentFiber = Option.getOrThrow(Fiber.getCurrentFiber())
|
|
37
41
|
|
|
38
|
-
|
|
42
|
+
yield* _(
|
|
39
43
|
Queue.take(backing.queue),
|
|
40
44
|
Effect.tap((req) => {
|
|
41
45
|
const id = req[0]
|
|
@@ -51,27 +55,58 @@ export const make = <I, R, E, O>(
|
|
|
51
55
|
Effect.matchCauseEffect(stream, {
|
|
52
56
|
onFailure: (cause) =>
|
|
53
57
|
Either.match(Cause.failureOrCause(cause), {
|
|
54
|
-
onLeft: (error) =>
|
|
58
|
+
onLeft: (error) => {
|
|
59
|
+
const transfers = options?.transfers ? options.transfers(error) : undefined
|
|
60
|
+
return pipe(
|
|
61
|
+
options?.encodeError ? options.encodeError(error) : Effect.succeed(error),
|
|
62
|
+
Effect.flatMap((payload) => backing.send([id, 2, payload as any], transfers)),
|
|
63
|
+
Effect.catchAllCause((cause) => backing.send([id, 3, Cause.squash(cause)]))
|
|
64
|
+
)
|
|
65
|
+
},
|
|
55
66
|
onRight: (cause) => backing.send([id, 3, Cause.squash(cause)])
|
|
56
67
|
}),
|
|
57
68
|
onSuccess: (data) => {
|
|
58
69
|
const transfers = options?.transfers ? options.transfers(data) : undefined
|
|
59
|
-
|
|
60
|
-
|
|
70
|
+
return pipe(
|
|
71
|
+
options?.encodeOutput ? options.encodeOutput(data) : Effect.succeed(data),
|
|
72
|
+
Effect.flatMap((payload) => backing.send([id, 0, [payload]], transfers)),
|
|
73
|
+
Effect.catchAllCause((cause) => backing.send([id, 3, Cause.squash(cause)]))
|
|
74
|
+
)
|
|
61
75
|
}
|
|
62
76
|
}) :
|
|
63
77
|
pipe(
|
|
64
78
|
stream,
|
|
65
|
-
Stream.
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
79
|
+
Stream.chunks,
|
|
80
|
+
Stream.tap((data) => {
|
|
81
|
+
if (options?.encodeOutput === undefined) {
|
|
82
|
+
const payload = Chunk.toReadonlyArray(data)
|
|
83
|
+
const transfers = options?.transfers ? payload.flatMap(options.transfers) : undefined
|
|
84
|
+
return backing.send([id, 0, payload], transfers)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const transfers: Array<unknown> = []
|
|
88
|
+
return Effect.flatMap(
|
|
89
|
+
Effect.forEach(data, (data) => {
|
|
90
|
+
if (options?.transfers) {
|
|
91
|
+
transfers.push(...options.transfers(data))
|
|
92
|
+
}
|
|
93
|
+
return Effect.orDie(options.encodeOutput!(data))
|
|
94
|
+
}),
|
|
95
|
+
(payload) => backing.send([id, 0, payload], transfers)
|
|
96
|
+
)
|
|
69
97
|
}),
|
|
70
98
|
Stream.runDrain,
|
|
71
99
|
Effect.matchCauseEffect({
|
|
72
100
|
onFailure: (cause) =>
|
|
73
101
|
Either.match(Cause.failureOrCause(cause), {
|
|
74
|
-
onLeft: (error) =>
|
|
102
|
+
onLeft: (error) => {
|
|
103
|
+
const transfers = options?.transfers ? options.transfers(error) : undefined
|
|
104
|
+
return pipe(
|
|
105
|
+
options?.encodeError ? options.encodeError(error) : Effect.succeed(error),
|
|
106
|
+
Effect.flatMap((payload) => backing.send([id, 2, payload as any], transfers)),
|
|
107
|
+
Effect.catchAllCause((cause) => backing.send([id, 3, Cause.squash(cause)]))
|
|
108
|
+
)
|
|
109
|
+
},
|
|
75
110
|
onRight: (cause) => backing.send([id, 3, Cause.squash(cause)])
|
|
76
111
|
}),
|
|
77
112
|
onSuccess: () => backing.send([id, 1])
|
|
@@ -85,17 +120,19 @@ export const make = <I, R, E, O>(
|
|
|
85
120
|
Effect.tap((fiber) => Effect.sync(() => fiberMap.set(id, fiber)))
|
|
86
121
|
)
|
|
87
122
|
}),
|
|
88
|
-
Effect.forever
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
return yield* _(
|
|
92
|
-
Effect.all([
|
|
93
|
-
handleRequests,
|
|
94
|
-
Fiber.join(backing.fiber)
|
|
95
|
-
], { concurrency: "unbounded", discard: true }) as Effect.Effect<R, WorkerError.WorkerError, never>
|
|
123
|
+
Effect.forever,
|
|
124
|
+
Effect.onInterrupt(() => Fiber.interrupt(parentFiber)),
|
|
125
|
+
Effect.forkScoped
|
|
96
126
|
)
|
|
97
127
|
})
|
|
98
128
|
|
|
129
|
+
/** @internal */
|
|
130
|
+
export const layer = <I, R, E, O>(
|
|
131
|
+
process: (request: I) => Stream.Stream<R, E, O> | Effect.Effect<R, E, O>,
|
|
132
|
+
options?: WorkerRunner.Runner.Options<E, O>
|
|
133
|
+
): Layer.Layer<WorkerRunner.PlatformRunner | R, WorkerError.WorkerError, never> =>
|
|
134
|
+
Layer.scopedDiscard(make(process, options))
|
|
135
|
+
|
|
99
136
|
/** @internal */
|
|
100
137
|
export const makeSerialized = <
|
|
101
138
|
I,
|
|
@@ -114,7 +151,7 @@ export const makeSerialized = <
|
|
|
114
151
|
| Scope.Scope
|
|
115
152
|
| (ReturnType<Handlers[keyof Handlers]> extends Stream.Stream<infer R, infer _E, infer _A> ? R : never),
|
|
116
153
|
WorkerError.WorkerError,
|
|
117
|
-
|
|
154
|
+
void
|
|
118
155
|
> => {
|
|
119
156
|
const parseRequest = Schema.decode(schema)
|
|
120
157
|
const effectTags = new Set<string>()
|
|
@@ -159,3 +196,23 @@ export const makeSerialized = <
|
|
|
159
196
|
}
|
|
160
197
|
})
|
|
161
198
|
}
|
|
199
|
+
|
|
200
|
+
/** @internal */
|
|
201
|
+
export const layerSerialized = <
|
|
202
|
+
I,
|
|
203
|
+
A extends Schema.TaggedRequest.Any,
|
|
204
|
+
const Handlers extends {
|
|
205
|
+
readonly [K in A["_tag"]]: Extract<A, { readonly _tag: K }> extends
|
|
206
|
+
Serializable.SerializableWithResult<infer _IS, infer S, infer _IE, infer E, infer _IO, infer O>
|
|
207
|
+
? (_: S) => Stream.Stream<any, E, O> | Effect.Effect<any, E, O> :
|
|
208
|
+
never
|
|
209
|
+
}
|
|
210
|
+
>(
|
|
211
|
+
schema: Schema.Schema<I, A>,
|
|
212
|
+
handlers: Handlers
|
|
213
|
+
): Layer.Layer<
|
|
214
|
+
| WorkerRunner.PlatformRunner
|
|
215
|
+
| (ReturnType<Handlers[keyof Handlers]> extends Stream.Stream<infer R, infer _E, infer _A> ? R : never),
|
|
216
|
+
WorkerError.WorkerError,
|
|
217
|
+
never
|
|
218
|
+
> => Layer.scopedDiscard(makeSerialized(schema, handlers))
|