@effect/platform 0.37.1 → 0.37.3
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/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 +40 -37
- package/dist/cjs/internal/worker.js.map +1 -1
- package/dist/cjs/internal/workerRunner.js +46 -43
- package/dist/cjs/internal/workerRunner.js.map +1 -1
- package/dist/dts/Worker.d.ts +1 -3
- package/dist/dts/Worker.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/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 +40 -37
- package/dist/esm/internal/worker.js.map +1 -1
- package/dist/esm/internal/workerRunner.js +44 -43
- package/dist/esm/internal/workerRunner.js.map +1 -1
- package/package.json +1 -1
- package/src/Worker.ts +2 -4
- package/src/WorkerRunner.ts +41 -9
- package/src/internal/worker.ts +85 -67
- package/src/internal/workerRunner.ts +86 -58
package/src/WorkerRunner.ts
CHANGED
|
@@ -5,7 +5,7 @@ import type * as Schema from "@effect/schema/Schema"
|
|
|
5
5
|
import type * as Serializable from "@effect/schema/Serializable"
|
|
6
6
|
import type * as Context from "effect/Context"
|
|
7
7
|
import type * as Effect from "effect/Effect"
|
|
8
|
-
import type * as
|
|
8
|
+
import type * as Layer from "effect/Layer"
|
|
9
9
|
import type * as Queue from "effect/Queue"
|
|
10
10
|
import type * as Scope from "effect/Scope"
|
|
11
11
|
import type * as Stream from "effect/Stream"
|
|
@@ -17,7 +17,6 @@ import type { WorkerError } from "./WorkerError.js"
|
|
|
17
17
|
* @category models
|
|
18
18
|
*/
|
|
19
19
|
export interface BackingRunner<I, O> {
|
|
20
|
-
readonly fiber: Fiber.Fiber<WorkerError, never>
|
|
21
20
|
readonly queue: Queue.Dequeue<I>
|
|
22
21
|
readonly send: (message: O, transfers?: ReadonlyArray<unknown>) => Effect.Effect<never, never, void>
|
|
23
22
|
}
|
|
@@ -70,9 +69,10 @@ export declare namespace Runner {
|
|
|
70
69
|
* @since 1.0.0
|
|
71
70
|
* @category models
|
|
72
71
|
*/
|
|
73
|
-
export interface Options<E, O> {
|
|
74
|
-
readonly
|
|
75
|
-
readonly
|
|
72
|
+
export interface Options<I, E, O> {
|
|
73
|
+
readonly decode?: (message: unknown) => Effect.Effect<never, WorkerError, I>
|
|
74
|
+
readonly encodeOutput?: (request: I, message: O) => Effect.Effect<never, WorkerError, unknown>
|
|
75
|
+
readonly encodeError?: (request: I, error: E) => Effect.Effect<never, WorkerError, unknown>
|
|
76
76
|
readonly transfers?: (message: O | E) => ReadonlyArray<unknown>
|
|
77
77
|
}
|
|
78
78
|
}
|
|
@@ -83,8 +83,17 @@ export declare namespace Runner {
|
|
|
83
83
|
*/
|
|
84
84
|
export const make: <I, R, E, O>(
|
|
85
85
|
process: (request: I) => Stream.Stream<R, E, O> | Effect.Effect<R, E, O>,
|
|
86
|
-
options?: Runner.Options<E, O> | undefined
|
|
87
|
-
) => Effect.Effect<Scope.Scope | R | PlatformRunner, WorkerError,
|
|
86
|
+
options?: Runner.Options<I, E, O> | undefined
|
|
87
|
+
) => Effect.Effect<Scope.Scope | R | PlatformRunner, WorkerError, void> = internal.make
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* @since 1.0.0
|
|
91
|
+
* @category layers
|
|
92
|
+
*/
|
|
93
|
+
export const layer: <I, R, E, O>(
|
|
94
|
+
process: (request: I) => Stream.Stream<R, E, O> | Effect.Effect<R, E, O>,
|
|
95
|
+
options?: Runner.Options<I, E, O> | undefined
|
|
96
|
+
) => Layer.Layer<R | PlatformRunner, WorkerError, never> = internal.layer
|
|
88
97
|
|
|
89
98
|
/**
|
|
90
99
|
* @since 1.0.0
|
|
@@ -93,7 +102,7 @@ export const make: <I, R, E, O>(
|
|
|
93
102
|
export const makeSerialized: <
|
|
94
103
|
I,
|
|
95
104
|
A extends Schema.TaggedRequest.Any,
|
|
96
|
-
Handlers extends {
|
|
105
|
+
const Handlers extends {
|
|
97
106
|
readonly [K in A["_tag"]]: Extract<A, { readonly _tag: K }> extends
|
|
98
107
|
Serializable.SerializableWithResult<infer _IS, infer S, infer _IE, infer E, infer _IO, infer O>
|
|
99
108
|
? (_: S) => Stream.Stream<any, E, O> | Effect.Effect<any, E, O> :
|
|
@@ -107,5 +116,28 @@ export const makeSerialized: <
|
|
|
107
116
|
| Scope.Scope
|
|
108
117
|
| (ReturnType<Handlers[keyof Handlers]> extends Stream.Stream<infer R, infer _E, infer _A> ? R : never),
|
|
109
118
|
WorkerError,
|
|
110
|
-
|
|
119
|
+
void
|
|
111
120
|
> = internal.makeSerialized
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* @since 1.0.0
|
|
124
|
+
* @category layers
|
|
125
|
+
*/
|
|
126
|
+
export const layerSerialized: <
|
|
127
|
+
I,
|
|
128
|
+
A extends Schema.TaggedRequest.Any,
|
|
129
|
+
const Handlers extends {
|
|
130
|
+
readonly [K in A["_tag"]]: Extract<A, { readonly _tag: K }> extends
|
|
131
|
+
Serializable.SerializableWithResult<infer _IS, infer S, infer _IE, infer E, infer _IO, infer O>
|
|
132
|
+
? (_: S) => Stream.Stream<any, E, O> | Effect.Effect<any, E, O> :
|
|
133
|
+
never
|
|
134
|
+
}
|
|
135
|
+
>(
|
|
136
|
+
schema: Schema.Schema<I, A>,
|
|
137
|
+
handlers: Handlers
|
|
138
|
+
) => Layer.Layer<
|
|
139
|
+
| PlatformRunner
|
|
140
|
+
| (ReturnType<Handlers[keyof Handlers]> extends Stream.Stream<infer R, infer _E, infer _A> ? R : never),
|
|
141
|
+
WorkerError,
|
|
142
|
+
never
|
|
143
|
+
> = internal.layerSerialized
|
package/src/internal/worker.ts
CHANGED
|
@@ -12,6 +12,8 @@ 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"
|
|
@@ -66,18 +68,60 @@ export const makeManager = Effect.gen(function*(_) {
|
|
|
66
68
|
return Effect.gen(function*(_) {
|
|
67
69
|
const id = idCounter++
|
|
68
70
|
let requestIdCounter = 0
|
|
69
|
-
const readyLatch = yield* _(Deferred.make<never, void>())
|
|
70
71
|
const semaphore = yield* _(Effect.makeSemaphore(permits))
|
|
71
72
|
const requestMap = new Map<
|
|
72
73
|
number,
|
|
73
|
-
readonly [Queue.Queue<Exit.Exit<E | WorkerError, O
|
|
74
|
+
readonly [Queue.Queue<Exit.Exit<E | WorkerError, ReadonlyArray<O>>>, Deferred.Deferred<never, void>]
|
|
74
75
|
>()
|
|
76
|
+
const sendQueue = yield* _(Effect.acquireRelease(
|
|
77
|
+
Queue.unbounded<readonly [message: Worker.Worker.Request, transfers?: ReadonlyArray<unknown>]>(),
|
|
78
|
+
Queue.shutdown
|
|
79
|
+
))
|
|
75
80
|
|
|
76
81
|
const outbound = queue ?? (yield* _(defaultQueue<I>()))
|
|
77
82
|
yield* _(Effect.addFinalizer(() => outbound.shutdown))
|
|
78
83
|
|
|
79
|
-
|
|
80
|
-
|
|
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
|
|
81
125
|
)
|
|
82
126
|
|
|
83
127
|
yield* _(Effect.addFinalizer(() =>
|
|
@@ -89,42 +133,34 @@ export const makeManager = Effect.gen(function*(_) {
|
|
|
89
133
|
)
|
|
90
134
|
))
|
|
91
135
|
|
|
92
|
-
const handleMessage = (
|
|
136
|
+
const handleMessage = (response: Worker.Worker.Response<E, O>) =>
|
|
93
137
|
Effect.suspend(() => {
|
|
94
|
-
|
|
138
|
+
const queue = requestMap.get(response[0])
|
|
139
|
+
if (!queue) return Effect.unit
|
|
140
|
+
|
|
141
|
+
switch (response[1]) {
|
|
142
|
+
// data
|
|
95
143
|
case 0: {
|
|
96
|
-
return
|
|
144
|
+
return Queue.offer(queue[0], Exit.succeed(response[2]))
|
|
97
145
|
}
|
|
146
|
+
// end
|
|
98
147
|
case 1: {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
)
|
|
116
|
-
}
|
|
117
|
-
// error / defect
|
|
118
|
-
case 2:
|
|
119
|
-
case 3: {
|
|
120
|
-
return Queue.offer(
|
|
121
|
-
queue[0],
|
|
122
|
-
response[1] === 2
|
|
123
|
-
? Exit.fail(response[2])
|
|
124
|
-
: Exit.die(response[2])
|
|
125
|
-
)
|
|
126
|
-
}
|
|
127
|
-
}
|
|
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
|
+
)
|
|
128
164
|
}
|
|
129
165
|
}
|
|
130
166
|
})
|
|
@@ -133,7 +169,7 @@ export const makeManager = Effect.gen(function*(_) {
|
|
|
133
169
|
Effect.tap(
|
|
134
170
|
Effect.all([
|
|
135
171
|
Effect.sync(() => requestIdCounter++),
|
|
136
|
-
Queue.unbounded<Exit.Exit<E | WorkerError, O
|
|
172
|
+
Queue.unbounded<Exit.Exit<E | WorkerError, ReadonlyArray<O>>>(),
|
|
137
173
|
Deferred.make<never, void>()
|
|
138
174
|
]),
|
|
139
175
|
([id, queue, deferred]) =>
|
|
@@ -144,7 +180,11 @@ export const makeManager = Effect.gen(function*(_) {
|
|
|
144
180
|
)
|
|
145
181
|
|
|
146
182
|
const executeRelease = (
|
|
147
|
-
[id, , deferred]: [
|
|
183
|
+
[id, , deferred]: [
|
|
184
|
+
number,
|
|
185
|
+
Queue.Queue<Exit.Exit<E | WorkerError, ReadonlyArray<O>>>,
|
|
186
|
+
Deferred.Deferred<never, void>
|
|
187
|
+
],
|
|
148
188
|
exit: Exit.Exit<unknown, unknown>
|
|
149
189
|
) => {
|
|
150
190
|
const release = Effect.zipRight(
|
|
@@ -152,10 +192,7 @@ export const makeManager = Effect.gen(function*(_) {
|
|
|
152
192
|
Effect.sync(() => requestMap.delete(id))
|
|
153
193
|
)
|
|
154
194
|
return Exit.isInterrupted(exit) ?
|
|
155
|
-
Effect.zipRight(
|
|
156
|
-
Effect.ignore(backing.send([id, 1])),
|
|
157
|
-
release
|
|
158
|
-
) :
|
|
195
|
+
Effect.zipRight(sendQueue.offer([[id, 1]]), release) :
|
|
159
196
|
release
|
|
160
197
|
}
|
|
161
198
|
|
|
@@ -171,7 +208,7 @@ export const makeManager = Effect.gen(function*(_) {
|
|
|
171
208
|
Queue.take(queue),
|
|
172
209
|
Exit.match({
|
|
173
210
|
onFailure: (cause) => Cause.isEmpty(cause) ? Channel.unit : Channel.failCause(cause),
|
|
174
|
-
onSuccess: (value) => Channel.flatMap(Channel.write(Chunk.
|
|
211
|
+
onSuccess: (value) => Channel.flatMap(Channel.write(Chunk.unsafeFromArray(value)), () => loop)
|
|
175
212
|
})
|
|
176
213
|
)
|
|
177
214
|
return Stream.fromChannel(loop)
|
|
@@ -181,18 +218,11 @@ export const makeManager = Effect.gen(function*(_) {
|
|
|
181
218
|
const executeEffect = (request: I) =>
|
|
182
219
|
Effect.acquireUseRelease(
|
|
183
220
|
executeAcquire(request),
|
|
184
|
-
([, queue]) => Effect.
|
|
221
|
+
([, queue]) => Effect.flatMap(Queue.take(queue), Exit.map(ReadonlyArray.unsafeGet(0))),
|
|
185
222
|
executeRelease
|
|
186
223
|
)
|
|
187
224
|
|
|
188
|
-
|
|
189
|
-
Queue.take(backing.queue),
|
|
190
|
-
Effect.flatMap(handleMessage),
|
|
191
|
-
Effect.forever,
|
|
192
|
-
Effect.forkScoped
|
|
193
|
-
)
|
|
194
|
-
|
|
195
|
-
const postMessages = pipe(
|
|
225
|
+
yield* _(
|
|
196
226
|
semaphore.take(1),
|
|
197
227
|
Effect.zipRight(outbound.take),
|
|
198
228
|
Effect.flatMap(([id, request]) =>
|
|
@@ -204,7 +234,7 @@ export const makeManager = Effect.gen(function*(_) {
|
|
|
204
234
|
return pipe(
|
|
205
235
|
Effect.flatMap(
|
|
206
236
|
encode ? encode(request) : Effect.succeed(request),
|
|
207
|
-
(payload) =>
|
|
237
|
+
(payload) => sendQueue.offer([[id, 0, payload], transferables])
|
|
208
238
|
),
|
|
209
239
|
Effect.catchAllCause((cause) => Queue.offer(result[0], Exit.failCause(cause))),
|
|
210
240
|
Effect.zipRight(Deferred.await(result[1]))
|
|
@@ -214,21 +244,10 @@ export const makeManager = Effect.gen(function*(_) {
|
|
|
214
244
|
Effect.fork
|
|
215
245
|
)
|
|
216
246
|
),
|
|
217
|
-
Effect.forever
|
|
218
|
-
)
|
|
219
|
-
|
|
220
|
-
const postMessagesFiber = yield* _(
|
|
221
|
-
Deferred.await(readyLatch),
|
|
222
|
-
Effect.zipRight(postMessages),
|
|
247
|
+
Effect.forever,
|
|
223
248
|
Effect.forkScoped
|
|
224
249
|
)
|
|
225
250
|
|
|
226
|
-
const join = Fiber.joinAll([backing.fiber, handleMessages, postMessagesFiber]) as Effect.Effect<
|
|
227
|
-
never,
|
|
228
|
-
WorkerError,
|
|
229
|
-
never
|
|
230
|
-
>
|
|
231
|
-
|
|
232
251
|
if (initialMessage) {
|
|
233
252
|
yield* _(
|
|
234
253
|
Effect.sync(initialMessage),
|
|
@@ -237,7 +256,7 @@ export const makeManager = Effect.gen(function*(_) {
|
|
|
237
256
|
)
|
|
238
257
|
}
|
|
239
258
|
|
|
240
|
-
return { id,
|
|
259
|
+
return { id, execute, executeEffect }
|
|
241
260
|
}).pipe(Effect.parallelFinalizers)
|
|
242
261
|
}
|
|
243
262
|
})
|
|
@@ -343,7 +362,6 @@ export const makeSerialized = <
|
|
|
343
362
|
}
|
|
344
363
|
return identity<Worker.SerializedWorker<I>>({
|
|
345
364
|
id: backing.id,
|
|
346
|
-
join: backing.join,
|
|
347
365
|
execute: execute as any,
|
|
348
366
|
executeEffect: executeEffect as any
|
|
349
367
|
})
|
|
@@ -1,18 +1,20 @@
|
|
|
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
|
-
import { pipe } from "effect/Function"
|
|
9
|
-
import * as
|
|
9
|
+
import { identity, pipe } from "effect/Function"
|
|
10
|
+
import * as Layer from "effect/Layer"
|
|
11
|
+
import * as Option from "effect/Option"
|
|
10
12
|
import * as Queue from "effect/Queue"
|
|
11
13
|
import type * as Scope from "effect/Scope"
|
|
12
14
|
import * as Stream from "effect/Stream"
|
|
13
15
|
import * as Transferable from "../Transferable.js"
|
|
14
16
|
import type * as Worker from "../Worker.js"
|
|
15
|
-
import
|
|
17
|
+
import * as WorkerError from "../WorkerError.js"
|
|
16
18
|
import type * as WorkerRunner from "../WorkerRunner.js"
|
|
17
19
|
|
|
18
20
|
/** @internal */
|
|
@@ -28,15 +30,25 @@ export const PlatformRunner = Context.Tag<WorkerRunner.PlatformRunner>(
|
|
|
28
30
|
/** @internal */
|
|
29
31
|
export const make = <I, R, E, O>(
|
|
30
32
|
process: (request: I) => Stream.Stream<R, E, O> | Effect.Effect<R, E, O>,
|
|
31
|
-
options?: WorkerRunner.Runner.Options<E, O>
|
|
33
|
+
options?: WorkerRunner.Runner.Options<I, E, O>
|
|
32
34
|
) =>
|
|
33
35
|
Effect.gen(function*(_) {
|
|
34
36
|
const platform = yield* _(PlatformRunner)
|
|
35
37
|
const backing = yield* _(platform.start<Worker.Worker.Request<I>, Worker.Worker.Response<E>>())
|
|
36
38
|
const fiberMap = new Map<number, Fiber.Fiber<never, void>>()
|
|
39
|
+
const parentFiber = Option.getOrThrow(Fiber.getCurrentFiber())
|
|
37
40
|
|
|
38
|
-
|
|
41
|
+
yield* _(
|
|
39
42
|
Queue.take(backing.queue),
|
|
43
|
+
options?.decode ?
|
|
44
|
+
Effect.flatMap((req): Effect.Effect<never, WorkerError.WorkerError, Worker.Worker.Request<I>> => {
|
|
45
|
+
if (req[1] === 1) {
|
|
46
|
+
return Effect.succeed(req)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return Effect.map(options.decode!(req[2]), (data) => [req[0], req[1], data])
|
|
50
|
+
}) :
|
|
51
|
+
identity,
|
|
40
52
|
Effect.tap((req) => {
|
|
41
53
|
const id = req[0]
|
|
42
54
|
if (req[1] === 1) {
|
|
@@ -54,7 +66,7 @@ export const make = <I, R, E, O>(
|
|
|
54
66
|
onLeft: (error) => {
|
|
55
67
|
const transfers = options?.transfers ? options.transfers(error) : undefined
|
|
56
68
|
return pipe(
|
|
57
|
-
options?.encodeError ? options.encodeError(error) : Effect.succeed(error),
|
|
69
|
+
options?.encodeError ? options.encodeError(req[2], error) : Effect.succeed(error),
|
|
58
70
|
Effect.flatMap((payload) => backing.send([id, 2, payload as any], transfers)),
|
|
59
71
|
Effect.catchAllCause((cause) => backing.send([id, 3, Cause.squash(cause)]))
|
|
60
72
|
)
|
|
@@ -64,18 +76,30 @@ export const make = <I, R, E, O>(
|
|
|
64
76
|
onSuccess: (data) => {
|
|
65
77
|
const transfers = options?.transfers ? options.transfers(data) : undefined
|
|
66
78
|
return pipe(
|
|
67
|
-
options?.encodeOutput ? options.encodeOutput(data) : Effect.succeed(data),
|
|
68
|
-
Effect.flatMap((payload) => backing.send([id, 0, payload], transfers)),
|
|
79
|
+
options?.encodeOutput ? options.encodeOutput(req[2], data) : Effect.succeed(data),
|
|
80
|
+
Effect.flatMap((payload) => backing.send([id, 0, [payload]], transfers)),
|
|
69
81
|
Effect.catchAllCause((cause) => backing.send([id, 3, Cause.squash(cause)]))
|
|
70
82
|
)
|
|
71
83
|
}
|
|
72
84
|
}) :
|
|
73
85
|
pipe(
|
|
74
86
|
stream,
|
|
87
|
+
Stream.chunks,
|
|
75
88
|
Stream.tap((data) => {
|
|
76
|
-
|
|
89
|
+
if (options?.encodeOutput === undefined) {
|
|
90
|
+
const payload = Chunk.toReadonlyArray(data)
|
|
91
|
+
const transfers = options?.transfers ? payload.flatMap(options.transfers) : undefined
|
|
92
|
+
return backing.send([id, 0, payload], transfers)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const transfers: Array<unknown> = []
|
|
77
96
|
return Effect.flatMap(
|
|
78
|
-
|
|
97
|
+
Effect.forEach(data, (data) => {
|
|
98
|
+
if (options?.transfers) {
|
|
99
|
+
transfers.push(...options.transfers(data))
|
|
100
|
+
}
|
|
101
|
+
return Effect.orDie(options.encodeOutput!(req[2], data))
|
|
102
|
+
}),
|
|
79
103
|
(payload) => backing.send([id, 0, payload], transfers)
|
|
80
104
|
)
|
|
81
105
|
}),
|
|
@@ -86,7 +110,7 @@ export const make = <I, R, E, O>(
|
|
|
86
110
|
onLeft: (error) => {
|
|
87
111
|
const transfers = options?.transfers ? options.transfers(error) : undefined
|
|
88
112
|
return pipe(
|
|
89
|
-
options?.encodeError ? options.encodeError(error) : Effect.succeed(error),
|
|
113
|
+
options?.encodeError ? options.encodeError(req[2], error) : Effect.succeed(error),
|
|
90
114
|
Effect.flatMap((payload) => backing.send([id, 2, payload as any], transfers)),
|
|
91
115
|
Effect.catchAllCause((cause) => backing.send([id, 3, Cause.squash(cause)]))
|
|
92
116
|
)
|
|
@@ -104,17 +128,19 @@ export const make = <I, R, E, O>(
|
|
|
104
128
|
Effect.tap((fiber) => Effect.sync(() => fiberMap.set(id, fiber)))
|
|
105
129
|
)
|
|
106
130
|
}),
|
|
107
|
-
Effect.forever
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
return yield* _(
|
|
111
|
-
Effect.all([
|
|
112
|
-
handleRequests,
|
|
113
|
-
Fiber.join(backing.fiber)
|
|
114
|
-
], { concurrency: "unbounded", discard: true }) as Effect.Effect<R, WorkerError.WorkerError, never>
|
|
131
|
+
Effect.forever,
|
|
132
|
+
Effect.onInterrupt(() => Fiber.interrupt(parentFiber)),
|
|
133
|
+
Effect.forkScoped
|
|
115
134
|
)
|
|
116
135
|
})
|
|
117
136
|
|
|
137
|
+
/** @internal */
|
|
138
|
+
export const layer = <I, R, E, O>(
|
|
139
|
+
process: (request: I) => Stream.Stream<R, E, O> | Effect.Effect<R, E, O>,
|
|
140
|
+
options?: WorkerRunner.Runner.Options<I, E, O>
|
|
141
|
+
): Layer.Layer<WorkerRunner.PlatformRunner | R, WorkerError.WorkerError, never> =>
|
|
142
|
+
Layer.scopedDiscard(make(process, options))
|
|
143
|
+
|
|
118
144
|
/** @internal */
|
|
119
145
|
export const makeSerialized = <
|
|
120
146
|
I,
|
|
@@ -133,48 +159,50 @@ export const makeSerialized = <
|
|
|
133
159
|
| Scope.Scope
|
|
134
160
|
| (ReturnType<Handlers[keyof Handlers]> extends Stream.Stream<infer R, infer _E, infer _A> ? R : never),
|
|
135
161
|
WorkerError.WorkerError,
|
|
136
|
-
|
|
162
|
+
void
|
|
137
163
|
> => {
|
|
138
|
-
const parseRequest = Schema.
|
|
139
|
-
|
|
140
|
-
return make((request: I) => {
|
|
141
|
-
if (Predicate.hasProperty(request, "_tag") && effectTags.has(request._tag as string)) {
|
|
142
|
-
return Effect.flatMap(parseRequest(request), (request: A) => {
|
|
143
|
-
const handler =
|
|
144
|
-
(handlers as unknown as Record<string, (req: unknown) => Effect.Effect<never, any, any>>)[request._tag]
|
|
145
|
-
if (!handler) {
|
|
146
|
-
return Effect.dieMessage(`No handler for ${request._tag}`)
|
|
147
|
-
}
|
|
148
|
-
const encodeSuccess = Schema.encode(Serializable.successSchema(request as any))
|
|
149
|
-
return pipe(
|
|
150
|
-
Effect.matchEffect(handler(request), {
|
|
151
|
-
onFailure: (error) => Effect.flatMap(Serializable.serializeFailure(request as any, error), Effect.fail),
|
|
152
|
-
onSuccess: encodeSuccess
|
|
153
|
-
})
|
|
154
|
-
)
|
|
155
|
-
})
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
return Stream.flatMap(parseRequest(request), (request: A) => {
|
|
159
|
-
const handler =
|
|
160
|
-
(handlers as unknown as Record<string, (req: unknown) => Stream.Stream<never, any, any>>)[request._tag]
|
|
161
|
-
if (!handler) {
|
|
162
|
-
return Stream.dieMessage(`No handler for ${request._tag}`)
|
|
163
|
-
}
|
|
164
|
-
const encodeSuccess = Schema.encode(Serializable.successSchema(request as any))
|
|
165
|
-
const stream = handler(request)
|
|
166
|
-
if (Effect.isEffect(stream)) {
|
|
167
|
-
effectTags.add(request._tag)
|
|
168
|
-
}
|
|
169
|
-
return pipe(
|
|
170
|
-
stream,
|
|
171
|
-
Stream.catchAll((error) => Effect.flatMap(Serializable.serializeFailure(request as any, error), Effect.fail)),
|
|
172
|
-
Stream.mapEffect(encodeSuccess)
|
|
173
|
-
)
|
|
174
|
-
})
|
|
175
|
-
}, {
|
|
164
|
+
const parseRequest = Schema.parse(schema)
|
|
165
|
+
return make((request: A) => (handlers as any)[request._tag](request), {
|
|
176
166
|
transfers(message) {
|
|
177
167
|
return Transferable.get(message)
|
|
168
|
+
},
|
|
169
|
+
decode(message) {
|
|
170
|
+
return Effect.mapError(
|
|
171
|
+
parseRequest(message),
|
|
172
|
+
(error) => WorkerError.WorkerError("decode", error)
|
|
173
|
+
)
|
|
174
|
+
},
|
|
175
|
+
encodeError(request, message) {
|
|
176
|
+
return Effect.mapError(
|
|
177
|
+
Serializable.serializeFailure(request as any, message),
|
|
178
|
+
(error) => WorkerError.WorkerError("encode", error)
|
|
179
|
+
)
|
|
180
|
+
},
|
|
181
|
+
encodeOutput(request, message) {
|
|
182
|
+
return Effect.mapError(
|
|
183
|
+
Serializable.serializeSuccess(request as any, message),
|
|
184
|
+
(error) => WorkerError.WorkerError("encode", error)
|
|
185
|
+
)
|
|
178
186
|
}
|
|
179
187
|
})
|
|
180
188
|
}
|
|
189
|
+
|
|
190
|
+
/** @internal */
|
|
191
|
+
export const layerSerialized = <
|
|
192
|
+
I,
|
|
193
|
+
A extends Schema.TaggedRequest.Any,
|
|
194
|
+
const Handlers extends {
|
|
195
|
+
readonly [K in A["_tag"]]: Extract<A, { readonly _tag: K }> extends
|
|
196
|
+
Serializable.SerializableWithResult<infer _IS, infer S, infer _IE, infer E, infer _IO, infer O>
|
|
197
|
+
? (_: S) => Stream.Stream<any, E, O> | Effect.Effect<any, E, O> :
|
|
198
|
+
never
|
|
199
|
+
}
|
|
200
|
+
>(
|
|
201
|
+
schema: Schema.Schema<I, A>,
|
|
202
|
+
handlers: Handlers
|
|
203
|
+
): Layer.Layer<
|
|
204
|
+
| WorkerRunner.PlatformRunner
|
|
205
|
+
| (ReturnType<Handlers[keyof Handlers]> extends Stream.Stream<infer R, infer _E, infer _A> ? R : never),
|
|
206
|
+
WorkerError.WorkerError,
|
|
207
|
+
never
|
|
208
|
+
> => Layer.scopedDiscard(makeSerialized(schema, handlers))
|