@effect/platform 0.26.4 → 0.26.6
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/Worker/dist/effect-platform-Worker.cjs.dev.js +23 -14
- package/Worker/dist/effect-platform-Worker.cjs.prod.js +23 -14
- package/Worker/dist/effect-platform-Worker.esm.js +24 -15
- package/dist/declarations/src/Worker.d.ts +9 -1
- package/dist/declarations/src/Worker.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/Worker.ts +9 -5
- package/src/internal/worker.ts +43 -25
|
@@ -78,6 +78,7 @@ const makeManager$1 = /*#__PURE__*/Effect__namespace.gen(function* (_) {
|
|
|
78
78
|
}) {
|
|
79
79
|
return Effect__namespace.gen(function* (_) {
|
|
80
80
|
const id = idCounter++;
|
|
81
|
+
const fiberId = yield* _(Effect__namespace.fiberId);
|
|
81
82
|
let requestIdCounter = 0;
|
|
82
83
|
const readyLatch = yield* _(Deferred__namespace.make());
|
|
83
84
|
const semaphore = yield* _(Effect__namespace.makeSemaphore(permits));
|
|
@@ -136,15 +137,20 @@ const makeManager$1 = /*#__PURE__*/Effect__namespace.gen(function* (_) {
|
|
|
136
137
|
return Stream__namespace.fromChannel(loop);
|
|
137
138
|
});
|
|
138
139
|
const executeEffect = request => Effect__namespace.acquireUseRelease(executeAcquire(request), ([, queue]) => Effect__namespace.flatten(Queue__namespace.take(queue)), executeRelease);
|
|
139
|
-
const handleMessages =
|
|
140
|
-
const postMessages =
|
|
140
|
+
const handleMessages = Function.pipe(Queue__namespace.take(backing.queue), Effect__namespace.flatMap(handleMessage), Effect__namespace.forever);
|
|
141
|
+
const postMessages = Function.pipe(semaphore.take(1), Effect__namespace.zipRight(outbound.take), Effect__namespace.flatMap(([id, request]) => Function.pipe(Effect__namespace.suspend(() => {
|
|
141
142
|
const result = requestMap.get(id);
|
|
142
143
|
if (!result) return Effect__namespace.unit;
|
|
143
144
|
const transferables = transfers(request);
|
|
144
145
|
const payload = encode ? encode(request) : request;
|
|
145
146
|
return Effect__namespace.zipRight(backing.send([id, 0, payload], transferables), Deferred__namespace.await(result[1]));
|
|
146
|
-
}), Effect__namespace.ensuring(semaphore.release(1)), Effect__namespace.fork)), Effect__namespace.forever
|
|
147
|
-
const
|
|
147
|
+
}), Effect__namespace.ensuring(semaphore.release(1)), Effect__namespace.fork)), Effect__namespace.forever);
|
|
148
|
+
const fiber = yield* _(Effect__namespace.all([backing.run, handleMessages, postMessages], {
|
|
149
|
+
concurrency: "unbounded",
|
|
150
|
+
discard: true
|
|
151
|
+
}), Effect__namespace.forkDaemon);
|
|
152
|
+
yield* _(Effect__namespace.addFinalizer(() => fiber.interruptAsFork(fiberId)));
|
|
153
|
+
const join = Fiber__namespace.join(fiber);
|
|
148
154
|
return {
|
|
149
155
|
id,
|
|
150
156
|
join,
|
|
@@ -162,20 +168,23 @@ const layerManager$1 = /*#__PURE__*/Layer__namespace.effect(WorkerManager$1, mak
|
|
|
162
168
|
/** @internal */
|
|
163
169
|
const makePool$1 = () => options => Effect__namespace.gen(function* (_) {
|
|
164
170
|
const manager = yield* _(WorkerManager$1);
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
acquire: manager.spawn(options),
|
|
171
|
+
const workers = new Set();
|
|
172
|
+
const acquire = Function.pipe(manager.spawn(options), Effect__namespace.tap(worker => Effect__namespace.sync(() => workers.add(worker))), Effect__namespace.tap(worker => Effect__namespace.addFinalizer(() => Effect__namespace.sync(() => workers.delete(worker)))), options.onCreate ? Effect__namespace.tap(options.onCreate) : Function.identity);
|
|
173
|
+
const backing = yield* _("timeToLive" in options ? Pool__namespace.makeWithTTL({
|
|
174
|
+
acquire,
|
|
175
|
+
min: options.minSize,
|
|
176
|
+
max: options.maxSize,
|
|
177
|
+
timeToLive: options.timeToLive
|
|
178
|
+
}) : Pool__namespace.make({
|
|
179
|
+
acquire,
|
|
175
180
|
size: options.size
|
|
176
181
|
}));
|
|
177
182
|
const pool = {
|
|
178
183
|
backing,
|
|
184
|
+
broadcast: message => Effect__namespace.forEach(workers, worker => worker.executeEffect(message), {
|
|
185
|
+
concurrency: "unbounded",
|
|
186
|
+
discard: true
|
|
187
|
+
}),
|
|
179
188
|
execute: message => Stream__namespace.unwrap(Effect__namespace.map(Effect__namespace.scoped(backing.get()), worker => worker.execute(message))),
|
|
180
189
|
executeEffect: message => Effect__namespace.flatMap(Effect__namespace.scoped(backing.get()), worker => worker.executeEffect(message))
|
|
181
190
|
};
|
|
@@ -78,6 +78,7 @@ const makeManager$1 = /*#__PURE__*/Effect__namespace.gen(function* (_) {
|
|
|
78
78
|
}) {
|
|
79
79
|
return Effect__namespace.gen(function* (_) {
|
|
80
80
|
const id = idCounter++;
|
|
81
|
+
const fiberId = yield* _(Effect__namespace.fiberId);
|
|
81
82
|
let requestIdCounter = 0;
|
|
82
83
|
const readyLatch = yield* _(Deferred__namespace.make());
|
|
83
84
|
const semaphore = yield* _(Effect__namespace.makeSemaphore(permits));
|
|
@@ -136,15 +137,20 @@ const makeManager$1 = /*#__PURE__*/Effect__namespace.gen(function* (_) {
|
|
|
136
137
|
return Stream__namespace.fromChannel(loop);
|
|
137
138
|
});
|
|
138
139
|
const executeEffect = request => Effect__namespace.acquireUseRelease(executeAcquire(request), ([, queue]) => Effect__namespace.flatten(Queue__namespace.take(queue)), executeRelease);
|
|
139
|
-
const handleMessages =
|
|
140
|
-
const postMessages =
|
|
140
|
+
const handleMessages = Function.pipe(Queue__namespace.take(backing.queue), Effect__namespace.flatMap(handleMessage), Effect__namespace.forever);
|
|
141
|
+
const postMessages = Function.pipe(semaphore.take(1), Effect__namespace.zipRight(outbound.take), Effect__namespace.flatMap(([id, request]) => Function.pipe(Effect__namespace.suspend(() => {
|
|
141
142
|
const result = requestMap.get(id);
|
|
142
143
|
if (!result) return Effect__namespace.unit;
|
|
143
144
|
const transferables = transfers(request);
|
|
144
145
|
const payload = encode ? encode(request) : request;
|
|
145
146
|
return Effect__namespace.zipRight(backing.send([id, 0, payload], transferables), Deferred__namespace.await(result[1]));
|
|
146
|
-
}), Effect__namespace.ensuring(semaphore.release(1)), Effect__namespace.fork)), Effect__namespace.forever
|
|
147
|
-
const
|
|
147
|
+
}), Effect__namespace.ensuring(semaphore.release(1)), Effect__namespace.fork)), Effect__namespace.forever);
|
|
148
|
+
const fiber = yield* _(Effect__namespace.all([backing.run, handleMessages, postMessages], {
|
|
149
|
+
concurrency: "unbounded",
|
|
150
|
+
discard: true
|
|
151
|
+
}), Effect__namespace.forkDaemon);
|
|
152
|
+
yield* _(Effect__namespace.addFinalizer(() => fiber.interruptAsFork(fiberId)));
|
|
153
|
+
const join = Fiber__namespace.join(fiber);
|
|
148
154
|
return {
|
|
149
155
|
id,
|
|
150
156
|
join,
|
|
@@ -162,20 +168,23 @@ const layerManager$1 = /*#__PURE__*/Layer__namespace.effect(WorkerManager$1, mak
|
|
|
162
168
|
/** @internal */
|
|
163
169
|
const makePool$1 = () => options => Effect__namespace.gen(function* (_) {
|
|
164
170
|
const manager = yield* _(WorkerManager$1);
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
acquire: manager.spawn(options),
|
|
171
|
+
const workers = new Set();
|
|
172
|
+
const acquire = Function.pipe(manager.spawn(options), Effect__namespace.tap(worker => Effect__namespace.sync(() => workers.add(worker))), Effect__namespace.tap(worker => Effect__namespace.addFinalizer(() => Effect__namespace.sync(() => workers.delete(worker)))), options.onCreate ? Effect__namespace.tap(options.onCreate) : Function.identity);
|
|
173
|
+
const backing = yield* _("timeToLive" in options ? Pool__namespace.makeWithTTL({
|
|
174
|
+
acquire,
|
|
175
|
+
min: options.minSize,
|
|
176
|
+
max: options.maxSize,
|
|
177
|
+
timeToLive: options.timeToLive
|
|
178
|
+
}) : Pool__namespace.make({
|
|
179
|
+
acquire,
|
|
175
180
|
size: options.size
|
|
176
181
|
}));
|
|
177
182
|
const pool = {
|
|
178
183
|
backing,
|
|
184
|
+
broadcast: message => Effect__namespace.forEach(workers, worker => worker.executeEffect(message), {
|
|
185
|
+
concurrency: "unbounded",
|
|
186
|
+
discard: true
|
|
187
|
+
}),
|
|
179
188
|
execute: message => Stream__namespace.unwrap(Effect__namespace.map(Effect__namespace.scoped(backing.get()), worker => worker.execute(message))),
|
|
180
189
|
executeEffect: message => Effect__namespace.flatMap(Effect__namespace.scoped(backing.get()), worker => worker.executeEffect(message))
|
|
181
190
|
};
|
|
@@ -5,7 +5,7 @@ import * as Deferred from 'effect/Deferred';
|
|
|
5
5
|
import * as Effect from 'effect/Effect';
|
|
6
6
|
import * as Exit from 'effect/Exit';
|
|
7
7
|
import * as Fiber from 'effect/Fiber';
|
|
8
|
-
import { pipe } from 'effect/Function';
|
|
8
|
+
import { pipe, identity } from 'effect/Function';
|
|
9
9
|
import * as Layer from 'effect/Layer';
|
|
10
10
|
import * as Pool from 'effect/Pool';
|
|
11
11
|
import * as Queue from 'effect/Queue';
|
|
@@ -45,6 +45,7 @@ const makeManager$1 = /*#__PURE__*/Effect.gen(function* (_) {
|
|
|
45
45
|
}) {
|
|
46
46
|
return Effect.gen(function* (_) {
|
|
47
47
|
const id = idCounter++;
|
|
48
|
+
const fiberId = yield* _(Effect.fiberId);
|
|
48
49
|
let requestIdCounter = 0;
|
|
49
50
|
const readyLatch = yield* _(Deferred.make());
|
|
50
51
|
const semaphore = yield* _(Effect.makeSemaphore(permits));
|
|
@@ -103,15 +104,20 @@ const makeManager$1 = /*#__PURE__*/Effect.gen(function* (_) {
|
|
|
103
104
|
return Stream.fromChannel(loop);
|
|
104
105
|
});
|
|
105
106
|
const executeEffect = request => Effect.acquireUseRelease(executeAcquire(request), ([, queue]) => Effect.flatten(Queue.take(queue)), executeRelease);
|
|
106
|
-
const handleMessages =
|
|
107
|
-
const postMessages =
|
|
107
|
+
const handleMessages = pipe(Queue.take(backing.queue), Effect.flatMap(handleMessage), Effect.forever);
|
|
108
|
+
const postMessages = pipe(semaphore.take(1), Effect.zipRight(outbound.take), Effect.flatMap(([id, request]) => pipe(Effect.suspend(() => {
|
|
108
109
|
const result = requestMap.get(id);
|
|
109
110
|
if (!result) return Effect.unit;
|
|
110
111
|
const transferables = transfers(request);
|
|
111
112
|
const payload = encode ? encode(request) : request;
|
|
112
113
|
return Effect.zipRight(backing.send([id, 0, payload], transferables), Deferred.await(result[1]));
|
|
113
|
-
}), Effect.ensuring(semaphore.release(1)), Effect.fork)), Effect.forever
|
|
114
|
-
const
|
|
114
|
+
}), Effect.ensuring(semaphore.release(1)), Effect.fork)), Effect.forever);
|
|
115
|
+
const fiber = yield* _(Effect.all([backing.run, handleMessages, postMessages], {
|
|
116
|
+
concurrency: "unbounded",
|
|
117
|
+
discard: true
|
|
118
|
+
}), Effect.forkDaemon);
|
|
119
|
+
yield* _(Effect.addFinalizer(() => fiber.interruptAsFork(fiberId)));
|
|
120
|
+
const join = Fiber.join(fiber);
|
|
115
121
|
return {
|
|
116
122
|
id,
|
|
117
123
|
join,
|
|
@@ -129,20 +135,23 @@ const layerManager$1 = /*#__PURE__*/Layer.effect(WorkerManager$1, makeManager$1)
|
|
|
129
135
|
/** @internal */
|
|
130
136
|
const makePool$1 = () => options => Effect.gen(function* (_) {
|
|
131
137
|
const manager = yield* _(WorkerManager$1);
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
acquire: manager.spawn(options),
|
|
138
|
+
const workers = new Set();
|
|
139
|
+
const acquire = pipe(manager.spawn(options), Effect.tap(worker => Effect.sync(() => workers.add(worker))), Effect.tap(worker => Effect.addFinalizer(() => Effect.sync(() => workers.delete(worker)))), options.onCreate ? Effect.tap(options.onCreate) : identity);
|
|
140
|
+
const backing = yield* _("timeToLive" in options ? Pool.makeWithTTL({
|
|
141
|
+
acquire,
|
|
142
|
+
min: options.minSize,
|
|
143
|
+
max: options.maxSize,
|
|
144
|
+
timeToLive: options.timeToLive
|
|
145
|
+
}) : Pool.make({
|
|
146
|
+
acquire,
|
|
142
147
|
size: options.size
|
|
143
148
|
}));
|
|
144
149
|
const pool = {
|
|
145
150
|
backing,
|
|
151
|
+
broadcast: message => Effect.forEach(workers, worker => worker.executeEffect(message), {
|
|
152
|
+
concurrency: "unbounded",
|
|
153
|
+
discard: true
|
|
154
|
+
}),
|
|
146
155
|
execute: message => Stream.unwrap(Effect.map(Effect.scoped(backing.get()), worker => worker.execute(message))),
|
|
147
156
|
executeEffect: message => Effect.flatMap(Effect.scoped(backing.get()), worker => worker.executeEffect(message))
|
|
148
157
|
};
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import type { Effect } from "effect";
|
|
5
5
|
import type * as Context from "effect/Context";
|
|
6
|
+
import type * as Duration from "effect/Duration";
|
|
6
7
|
import type * as Layer from "effect/Layer";
|
|
7
8
|
import type * as Pool from "effect/Pool";
|
|
8
9
|
import type * as Queue from "effect/Queue";
|
|
@@ -14,7 +15,7 @@ import type { WorkerError } from "./WorkerError.js";
|
|
|
14
15
|
* @category models
|
|
15
16
|
*/
|
|
16
17
|
export interface BackingWorker<I, O> {
|
|
17
|
-
readonly
|
|
18
|
+
readonly run: Effect.Effect<never, WorkerError, never>;
|
|
18
19
|
readonly send: (message: I, transfers?: ReadonlyArray<unknown>) => Effect.Effect<never, never, void>;
|
|
19
20
|
readonly queue: Queue.Dequeue<BackingWorker.Message<O>>;
|
|
20
21
|
}
|
|
@@ -95,6 +96,7 @@ export declare namespace Worker {
|
|
|
95
96
|
*/
|
|
96
97
|
export interface WorkerPool<I, E, O> {
|
|
97
98
|
readonly backing: Pool.Pool<WorkerError, Worker<I, E, O>>;
|
|
99
|
+
readonly broadcast: (message: I) => Effect.Effect<never, E | WorkerError, void>;
|
|
98
100
|
readonly execute: (message: I) => Stream.Stream<never, E | WorkerError, O>;
|
|
99
101
|
readonly executeEffect: (message: I) => Effect.Effect<never, E | WorkerError, O>;
|
|
100
102
|
}
|
|
@@ -108,7 +110,13 @@ export declare namespace WorkerPool {
|
|
|
108
110
|
* @category models
|
|
109
111
|
*/
|
|
110
112
|
type Options<I, W = unknown> = Worker.Options<I, W> & ({
|
|
113
|
+
readonly onCreate?: (worker: Worker<I, unknown, unknown>) => Effect.Effect<never, WorkerError, void>;
|
|
111
114
|
readonly size: number;
|
|
115
|
+
} | {
|
|
116
|
+
readonly onCreate?: (worker: Worker<I, unknown, unknown>) => Effect.Effect<never, WorkerError, void>;
|
|
117
|
+
readonly minSize: number;
|
|
118
|
+
readonly maxSize: number;
|
|
119
|
+
readonly timeToLive: Duration.DurationInput;
|
|
112
120
|
});
|
|
113
121
|
}
|
|
114
122
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Worker.d.ts","sourceRoot":"../../../src","sources":["Worker.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AACpC,OAAO,KAAK,KAAK,OAAO,MAAM,gBAAgB,CAAA;AAC9C,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAA;AAC1C,OAAO,KAAK,KAAK,IAAI,MAAM,aAAa,CAAA;AACxC,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAA;AAC1C,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAA;AAC1C,OAAO,KAAK,KAAK,MAAM,MAAM,eAAe,CAAA;AAE5C,OAAO,KAAK,EAAE,WAAW,EAAE,yBAAqB;AAEhD;;;GAGG;AACH,MAAM,WAAW,aAAa,CAAC,CAAC,EAAE,CAAC;IACjC,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"Worker.d.ts","sourceRoot":"../../../src","sources":["Worker.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/Worker.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import type { Effect } from "effect"
|
|
5
5
|
import type * as Context from "effect/Context"
|
|
6
|
+
import type * as Duration from "effect/Duration"
|
|
6
7
|
import type * as Layer from "effect/Layer"
|
|
7
8
|
import type * as Pool from "effect/Pool"
|
|
8
9
|
import type * as Queue from "effect/Queue"
|
|
@@ -16,7 +17,7 @@ import type { WorkerError } from "./WorkerError"
|
|
|
16
17
|
* @category models
|
|
17
18
|
*/
|
|
18
19
|
export interface BackingWorker<I, O> {
|
|
19
|
-
readonly
|
|
20
|
+
readonly run: Effect.Effect<never, WorkerError, never>
|
|
20
21
|
readonly send: (message: I, transfers?: ReadonlyArray<unknown>) => Effect.Effect<never, never, void>
|
|
21
22
|
readonly queue: Queue.Dequeue<BackingWorker.Message<O>>
|
|
22
23
|
}
|
|
@@ -112,6 +113,7 @@ export declare namespace Worker {
|
|
|
112
113
|
*/
|
|
113
114
|
export interface WorkerPool<I, E, O> {
|
|
114
115
|
readonly backing: Pool.Pool<WorkerError, Worker<I, E, O>>
|
|
116
|
+
readonly broadcast: (message: I) => Effect.Effect<never, E | WorkerError, void>
|
|
115
117
|
readonly execute: (message: I) => Stream.Stream<never, E | WorkerError, O>
|
|
116
118
|
readonly executeEffect: (message: I) => Effect.Effect<never, E | WorkerError, O>
|
|
117
119
|
}
|
|
@@ -128,11 +130,13 @@ export declare namespace WorkerPool {
|
|
|
128
130
|
export type Options<I, W = unknown> =
|
|
129
131
|
& Worker.Options<I, W>
|
|
130
132
|
& ({
|
|
133
|
+
readonly onCreate?: (worker: Worker<I, unknown, unknown>) => Effect.Effect<never, WorkerError, void>
|
|
131
134
|
readonly size: number
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
135
|
+
} | {
|
|
136
|
+
readonly onCreate?: (worker: Worker<I, unknown, unknown>) => Effect.Effect<never, WorkerError, void>
|
|
137
|
+
readonly minSize: number
|
|
138
|
+
readonly maxSize: number
|
|
139
|
+
readonly timeToLive: Duration.DurationInput
|
|
136
140
|
})
|
|
137
141
|
}
|
|
138
142
|
|
package/src/internal/worker.ts
CHANGED
|
@@ -5,7 +5,7 @@ import * as Deferred from "effect/Deferred"
|
|
|
5
5
|
import * as Effect from "effect/Effect"
|
|
6
6
|
import * as Exit from "effect/Exit"
|
|
7
7
|
import * as Fiber from "effect/Fiber"
|
|
8
|
-
import { pipe } from "effect/Function"
|
|
8
|
+
import { identity, pipe } from "effect/Function"
|
|
9
9
|
import * as Layer from "effect/Layer"
|
|
10
10
|
import * as Pool from "effect/Pool"
|
|
11
11
|
import * as Queue from "effect/Queue"
|
|
@@ -53,6 +53,7 @@ export const makeManager = Effect.gen(function*(_) {
|
|
|
53
53
|
spawn<I, E, O>({ encode, permits = 1, queue, spawn, transfers = (_) => [] }: Worker.Worker.Options<I>) {
|
|
54
54
|
return Effect.gen(function*(_) {
|
|
55
55
|
const id = idCounter++
|
|
56
|
+
const fiberId = yield* _(Effect.fiberId)
|
|
56
57
|
let requestIdCounter = 0
|
|
57
58
|
const readyLatch = yield* _(Deferred.make<never, void>())
|
|
58
59
|
const semaphore = yield* _(Effect.makeSemaphore(permits))
|
|
@@ -169,14 +170,13 @@ export const makeManager = Effect.gen(function*(_) {
|
|
|
169
170
|
executeRelease
|
|
170
171
|
)
|
|
171
172
|
|
|
172
|
-
const handleMessages =
|
|
173
|
+
const handleMessages = pipe(
|
|
173
174
|
Queue.take(backing.queue),
|
|
174
175
|
Effect.flatMap(handleMessage),
|
|
175
|
-
Effect.forever
|
|
176
|
-
Effect.forkScoped
|
|
176
|
+
Effect.forever
|
|
177
177
|
)
|
|
178
178
|
|
|
179
|
-
const postMessages =
|
|
179
|
+
const postMessages = pipe(
|
|
180
180
|
semaphore.take(1),
|
|
181
181
|
Effect.zipRight(outbound.take),
|
|
182
182
|
Effect.flatMap(([id, request]) =>
|
|
@@ -195,17 +195,23 @@ export const makeManager = Effect.gen(function*(_) {
|
|
|
195
195
|
Effect.fork
|
|
196
196
|
)
|
|
197
197
|
),
|
|
198
|
-
Effect.forever
|
|
199
|
-
Effect.forkScoped
|
|
198
|
+
Effect.forever
|
|
200
199
|
)
|
|
201
200
|
|
|
202
|
-
const
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
201
|
+
const fiber = yield* _(
|
|
202
|
+
Effect.all([backing.run, handleMessages, postMessages], {
|
|
203
|
+
concurrency: "unbounded",
|
|
204
|
+
discard: true
|
|
205
|
+
}) as Effect.Effect<
|
|
206
|
+
never,
|
|
207
|
+
WorkerError,
|
|
208
|
+
never
|
|
209
|
+
>,
|
|
210
|
+
Effect.forkDaemon
|
|
211
|
+
)
|
|
212
|
+
yield* _(Effect.addFinalizer(() => fiber.interruptAsFork(fiberId)))
|
|
213
|
+
|
|
214
|
+
const join = Fiber.join(fiber)
|
|
209
215
|
|
|
210
216
|
return { id, join, execute, executeEffect }
|
|
211
217
|
})
|
|
@@ -223,21 +229,33 @@ export const makePool = <W>() =>
|
|
|
223
229
|
) =>
|
|
224
230
|
Effect.gen(function*(_) {
|
|
225
231
|
const manager = yield* _(WorkerManager)
|
|
232
|
+
const workers = new Set<Worker.Worker<I, E, O>>()
|
|
233
|
+
const acquire = pipe(
|
|
234
|
+
manager.spawn<I, E, O>(options),
|
|
235
|
+
Effect.tap((worker) => Effect.sync(() => workers.add(worker))),
|
|
236
|
+
Effect.tap((worker) => Effect.addFinalizer(() => Effect.sync(() => workers.delete(worker)))),
|
|
237
|
+
options.onCreate ? Effect.tap(options.onCreate) : identity
|
|
238
|
+
)
|
|
226
239
|
const backing = yield* _(
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
240
|
+
"timeToLive" in options ?
|
|
241
|
+
Pool.makeWithTTL({
|
|
242
|
+
acquire,
|
|
243
|
+
min: options.minSize,
|
|
244
|
+
max: options.maxSize,
|
|
245
|
+
timeToLive: options.timeToLive
|
|
246
|
+
}) :
|
|
247
|
+
Pool.make({
|
|
248
|
+
acquire,
|
|
249
|
+
size: options.size
|
|
250
|
+
})
|
|
238
251
|
)
|
|
239
252
|
const pool: Worker.WorkerPool<I, E, O> = {
|
|
240
253
|
backing,
|
|
254
|
+
broadcast: (message: I) =>
|
|
255
|
+
Effect.forEach(workers, (worker) => worker.executeEffect(message), {
|
|
256
|
+
concurrency: "unbounded",
|
|
257
|
+
discard: true
|
|
258
|
+
}),
|
|
241
259
|
execute: (message: I) =>
|
|
242
260
|
Stream.unwrap(
|
|
243
261
|
Effect.map(
|