@effect/platform 0.26.3 → 0.26.5
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 +30 -16
- package/Worker/dist/effect-platform-Worker.cjs.prod.js +30 -16
- package/Worker/dist/effect-platform-Worker.esm.js +30 -17
- package/dist/declarations/src/Worker.d.ts +2 -5
- package/dist/declarations/src/Worker.d.ts.map +1 -1
- package/dist/declarations/src/WorkerRunner.d.ts +2 -2
- package/dist/declarations/src/WorkerRunner.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/Worker.ts +6 -5
- package/src/WorkerRunner.ts +2 -2
- package/src/internal/worker.ts +47 -29
- package/src/internal/workerRunner.ts +2 -1
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
+
var effect = require('effect');
|
|
6
|
+
var Channel = require('effect/Channel');
|
|
5
7
|
var Context = require('effect/Context');
|
|
6
8
|
var Deferred = require('effect/Deferred');
|
|
7
9
|
var Effect = require('effect/Effect');
|
|
@@ -31,6 +33,7 @@ function _interopNamespace(e) {
|
|
|
31
33
|
return Object.freeze(n);
|
|
32
34
|
}
|
|
33
35
|
|
|
36
|
+
var Channel__namespace = /*#__PURE__*/_interopNamespace(Channel);
|
|
34
37
|
var Context__namespace = /*#__PURE__*/_interopNamespace(Context);
|
|
35
38
|
var Deferred__namespace = /*#__PURE__*/_interopNamespace(Deferred);
|
|
36
39
|
var Effect__namespace = /*#__PURE__*/_interopNamespace(Effect);
|
|
@@ -75,7 +78,6 @@ const makeManager$1 = /*#__PURE__*/Effect__namespace.gen(function* (_) {
|
|
|
75
78
|
}) {
|
|
76
79
|
return Effect__namespace.gen(function* (_) {
|
|
77
80
|
const id = idCounter++;
|
|
78
|
-
const fiberId = yield* _(Effect__namespace.fiberId);
|
|
79
81
|
let requestIdCounter = 0;
|
|
80
82
|
const readyLatch = yield* _(Deferred__namespace.make());
|
|
81
83
|
const semaphore = yield* _(Effect__namespace.makeSemaphore(permits));
|
|
@@ -83,7 +85,7 @@ const makeManager$1 = /*#__PURE__*/Effect__namespace.gen(function* (_) {
|
|
|
83
85
|
const outbound = queue ?? (yield* _(defaultQueue()));
|
|
84
86
|
yield* _(Effect__namespace.addFinalizer(() => outbound.shutdown));
|
|
85
87
|
const backing = yield* _(platform.spawn(spawn(id)));
|
|
86
|
-
yield* _(Effect__namespace.addFinalizer(() => Effect__namespace.zipRight(Effect__namespace.forEach(requestMap.values(), ([queue]) => Queue__namespace.
|
|
88
|
+
yield* _(Effect__namespace.addFinalizer(() => Effect__namespace.zipRight(Effect__namespace.forEach(requestMap.values(), ([queue]) => Queue__namespace.offer(queue, Exit__namespace.failCause(effect.Cause.empty)), {
|
|
87
89
|
discard: true
|
|
88
90
|
}), Effect__namespace.sync(() => requestMap.clear()))));
|
|
89
91
|
const handleMessage = msg => Effect__namespace.suspend(() => {
|
|
@@ -106,13 +108,13 @@ const makeManager$1 = /*#__PURE__*/Effect__namespace.gen(function* (_) {
|
|
|
106
108
|
// end
|
|
107
109
|
case 1:
|
|
108
110
|
{
|
|
109
|
-
return response.length === 2 ? Queue__namespace.
|
|
111
|
+
return response.length === 2 ? Queue__namespace.offer(queue[0], Exit__namespace.failCause(effect.Cause.empty)) : Effect__namespace.zipRight(Queue__namespace.offer(queue[0], Exit__namespace.succeed(response[2])), Queue__namespace.offer(queue[0], Exit__namespace.failCause(effect.Cause.empty)));
|
|
110
112
|
}
|
|
111
113
|
// error / defect
|
|
112
114
|
case 2:
|
|
113
115
|
case 3:
|
|
114
116
|
{
|
|
115
|
-
return
|
|
117
|
+
return Queue__namespace.offer(queue[0], response[1] === 2 ? Exit__namespace.fail(response[2]) : Exit__namespace.die(response[2]));
|
|
116
118
|
}
|
|
117
119
|
}
|
|
118
120
|
}
|
|
@@ -126,18 +128,22 @@ const makeManager$1 = /*#__PURE__*/Effect__namespace.gen(function* (_) {
|
|
|
126
128
|
const release = Effect__namespace.zipRight(Deferred__namespace.complete(deferred, Effect__namespace.unit), Effect__namespace.sync(() => requestMap.delete(id)));
|
|
127
129
|
return Exit__namespace.isInterrupted(exit) ? Effect__namespace.zipRight(backing.send([id, 1]), release) : release;
|
|
128
130
|
};
|
|
129
|
-
const execute = request => Stream__namespace.flatMap(Stream__namespace.acquireRelease(executeAcquire(request), executeRelease), ([, queue]) =>
|
|
131
|
+
const execute = request => Stream__namespace.flatMap(Stream__namespace.acquireRelease(executeAcquire(request), executeRelease), ([, queue]) => {
|
|
132
|
+
const loop = Channel__namespace.flatMap(Queue__namespace.take(queue), Exit__namespace.match({
|
|
133
|
+
onFailure: cause => effect.Cause.isEmpty(cause) ? Channel__namespace.unit : Channel__namespace.failCause(cause),
|
|
134
|
+
onSuccess: value => Channel__namespace.flatMap(Channel__namespace.write(effect.Chunk.of(value)), () => loop)
|
|
135
|
+
}));
|
|
136
|
+
return Stream__namespace.fromChannel(loop);
|
|
137
|
+
});
|
|
130
138
|
const executeEffect = request => Effect__namespace.acquireUseRelease(executeAcquire(request), ([, queue]) => Effect__namespace.flatten(Queue__namespace.take(queue)), executeRelease);
|
|
131
|
-
const handleMessages = yield* _(Queue__namespace.take(backing.queue), Effect__namespace.flatMap(handleMessage), Effect__namespace.forever, Effect__namespace.
|
|
132
|
-
yield* _(Effect__namespace.addFinalizer(() => handleMessages.interruptAsFork(fiberId)));
|
|
139
|
+
const handleMessages = yield* _(Queue__namespace.take(backing.queue), Effect__namespace.flatMap(handleMessage), Effect__namespace.forever, Effect__namespace.forkScoped);
|
|
133
140
|
const postMessages = yield* _(semaphore.take(1), Effect__namespace.zipRight(outbound.take), Effect__namespace.flatMap(([id, request]) => Function.pipe(Effect__namespace.suspend(() => {
|
|
134
141
|
const result = requestMap.get(id);
|
|
135
142
|
if (!result) return Effect__namespace.unit;
|
|
136
143
|
const transferables = transfers(request);
|
|
137
144
|
const payload = encode ? encode(request) : request;
|
|
138
145
|
return Effect__namespace.zipRight(backing.send([id, 0, payload], transferables), Deferred__namespace.await(result[1]));
|
|
139
|
-
}), Effect__namespace.ensuring(semaphore.release(1)), Effect__namespace.fork)), Effect__namespace.forever, Effect__namespace.
|
|
140
|
-
yield* _(Effect__namespace.addFinalizer(() => postMessages.interruptAsFork(fiberId)));
|
|
146
|
+
}), Effect__namespace.ensuring(semaphore.release(1)), Effect__namespace.fork)), Effect__namespace.forever, Effect__namespace.forkScoped);
|
|
141
147
|
const join = Effect__namespace.race(Fiber__namespace.joinAll([handleMessages, postMessages]), backing.join);
|
|
142
148
|
return {
|
|
143
149
|
id,
|
|
@@ -156,17 +162,25 @@ const layerManager$1 = /*#__PURE__*/Layer__namespace.effect(WorkerManager$1, mak
|
|
|
156
162
|
/** @internal */
|
|
157
163
|
const makePool$1 = () => options => Effect__namespace.gen(function* (_) {
|
|
158
164
|
const manager = yield* _(WorkerManager$1);
|
|
159
|
-
const
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
165
|
+
const workers = new Set();
|
|
166
|
+
const backing = yield* _(
|
|
167
|
+
// "timeToLive" in options ?
|
|
168
|
+
// Pool.makeWithTTL({
|
|
169
|
+
// acquire: manager.spawn<I, E, O>(options),
|
|
170
|
+
// min: options.minSize,
|
|
171
|
+
// max: options.maxSize,
|
|
172
|
+
// timeToLive: options.timeToLive
|
|
173
|
+
// }) :
|
|
174
|
+
Pool__namespace.make({
|
|
175
|
+
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),
|
|
166
176
|
size: options.size
|
|
167
177
|
}));
|
|
168
178
|
const pool = {
|
|
169
179
|
backing,
|
|
180
|
+
broadcast: message => Effect__namespace.forEach(workers, worker => worker.executeEffect(message), {
|
|
181
|
+
concurrency: "unbounded",
|
|
182
|
+
discard: true
|
|
183
|
+
}),
|
|
170
184
|
execute: message => Stream__namespace.unwrap(Effect__namespace.map(Effect__namespace.scoped(backing.get()), worker => worker.execute(message))),
|
|
171
185
|
executeEffect: message => Effect__namespace.flatMap(Effect__namespace.scoped(backing.get()), worker => worker.executeEffect(message))
|
|
172
186
|
};
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
+
var effect = require('effect');
|
|
6
|
+
var Channel = require('effect/Channel');
|
|
5
7
|
var Context = require('effect/Context');
|
|
6
8
|
var Deferred = require('effect/Deferred');
|
|
7
9
|
var Effect = require('effect/Effect');
|
|
@@ -31,6 +33,7 @@ function _interopNamespace(e) {
|
|
|
31
33
|
return Object.freeze(n);
|
|
32
34
|
}
|
|
33
35
|
|
|
36
|
+
var Channel__namespace = /*#__PURE__*/_interopNamespace(Channel);
|
|
34
37
|
var Context__namespace = /*#__PURE__*/_interopNamespace(Context);
|
|
35
38
|
var Deferred__namespace = /*#__PURE__*/_interopNamespace(Deferred);
|
|
36
39
|
var Effect__namespace = /*#__PURE__*/_interopNamespace(Effect);
|
|
@@ -75,7 +78,6 @@ const makeManager$1 = /*#__PURE__*/Effect__namespace.gen(function* (_) {
|
|
|
75
78
|
}) {
|
|
76
79
|
return Effect__namespace.gen(function* (_) {
|
|
77
80
|
const id = idCounter++;
|
|
78
|
-
const fiberId = yield* _(Effect__namespace.fiberId);
|
|
79
81
|
let requestIdCounter = 0;
|
|
80
82
|
const readyLatch = yield* _(Deferred__namespace.make());
|
|
81
83
|
const semaphore = yield* _(Effect__namespace.makeSemaphore(permits));
|
|
@@ -83,7 +85,7 @@ const makeManager$1 = /*#__PURE__*/Effect__namespace.gen(function* (_) {
|
|
|
83
85
|
const outbound = queue ?? (yield* _(defaultQueue()));
|
|
84
86
|
yield* _(Effect__namespace.addFinalizer(() => outbound.shutdown));
|
|
85
87
|
const backing = yield* _(platform.spawn(spawn(id)));
|
|
86
|
-
yield* _(Effect__namespace.addFinalizer(() => Effect__namespace.zipRight(Effect__namespace.forEach(requestMap.values(), ([queue]) => Queue__namespace.
|
|
88
|
+
yield* _(Effect__namespace.addFinalizer(() => Effect__namespace.zipRight(Effect__namespace.forEach(requestMap.values(), ([queue]) => Queue__namespace.offer(queue, Exit__namespace.failCause(effect.Cause.empty)), {
|
|
87
89
|
discard: true
|
|
88
90
|
}), Effect__namespace.sync(() => requestMap.clear()))));
|
|
89
91
|
const handleMessage = msg => Effect__namespace.suspend(() => {
|
|
@@ -106,13 +108,13 @@ const makeManager$1 = /*#__PURE__*/Effect__namespace.gen(function* (_) {
|
|
|
106
108
|
// end
|
|
107
109
|
case 1:
|
|
108
110
|
{
|
|
109
|
-
return response.length === 2 ? Queue__namespace.
|
|
111
|
+
return response.length === 2 ? Queue__namespace.offer(queue[0], Exit__namespace.failCause(effect.Cause.empty)) : Effect__namespace.zipRight(Queue__namespace.offer(queue[0], Exit__namespace.succeed(response[2])), Queue__namespace.offer(queue[0], Exit__namespace.failCause(effect.Cause.empty)));
|
|
110
112
|
}
|
|
111
113
|
// error / defect
|
|
112
114
|
case 2:
|
|
113
115
|
case 3:
|
|
114
116
|
{
|
|
115
|
-
return
|
|
117
|
+
return Queue__namespace.offer(queue[0], response[1] === 2 ? Exit__namespace.fail(response[2]) : Exit__namespace.die(response[2]));
|
|
116
118
|
}
|
|
117
119
|
}
|
|
118
120
|
}
|
|
@@ -126,18 +128,22 @@ const makeManager$1 = /*#__PURE__*/Effect__namespace.gen(function* (_) {
|
|
|
126
128
|
const release = Effect__namespace.zipRight(Deferred__namespace.complete(deferred, Effect__namespace.unit), Effect__namespace.sync(() => requestMap.delete(id)));
|
|
127
129
|
return Exit__namespace.isInterrupted(exit) ? Effect__namespace.zipRight(backing.send([id, 1]), release) : release;
|
|
128
130
|
};
|
|
129
|
-
const execute = request => Stream__namespace.flatMap(Stream__namespace.acquireRelease(executeAcquire(request), executeRelease), ([, queue]) =>
|
|
131
|
+
const execute = request => Stream__namespace.flatMap(Stream__namespace.acquireRelease(executeAcquire(request), executeRelease), ([, queue]) => {
|
|
132
|
+
const loop = Channel__namespace.flatMap(Queue__namespace.take(queue), Exit__namespace.match({
|
|
133
|
+
onFailure: cause => effect.Cause.isEmpty(cause) ? Channel__namespace.unit : Channel__namespace.failCause(cause),
|
|
134
|
+
onSuccess: value => Channel__namespace.flatMap(Channel__namespace.write(effect.Chunk.of(value)), () => loop)
|
|
135
|
+
}));
|
|
136
|
+
return Stream__namespace.fromChannel(loop);
|
|
137
|
+
});
|
|
130
138
|
const executeEffect = request => Effect__namespace.acquireUseRelease(executeAcquire(request), ([, queue]) => Effect__namespace.flatten(Queue__namespace.take(queue)), executeRelease);
|
|
131
|
-
const handleMessages = yield* _(Queue__namespace.take(backing.queue), Effect__namespace.flatMap(handleMessage), Effect__namespace.forever, Effect__namespace.
|
|
132
|
-
yield* _(Effect__namespace.addFinalizer(() => handleMessages.interruptAsFork(fiberId)));
|
|
139
|
+
const handleMessages = yield* _(Queue__namespace.take(backing.queue), Effect__namespace.flatMap(handleMessage), Effect__namespace.forever, Effect__namespace.forkScoped);
|
|
133
140
|
const postMessages = yield* _(semaphore.take(1), Effect__namespace.zipRight(outbound.take), Effect__namespace.flatMap(([id, request]) => Function.pipe(Effect__namespace.suspend(() => {
|
|
134
141
|
const result = requestMap.get(id);
|
|
135
142
|
if (!result) return Effect__namespace.unit;
|
|
136
143
|
const transferables = transfers(request);
|
|
137
144
|
const payload = encode ? encode(request) : request;
|
|
138
145
|
return Effect__namespace.zipRight(backing.send([id, 0, payload], transferables), Deferred__namespace.await(result[1]));
|
|
139
|
-
}), Effect__namespace.ensuring(semaphore.release(1)), Effect__namespace.fork)), Effect__namespace.forever, Effect__namespace.
|
|
140
|
-
yield* _(Effect__namespace.addFinalizer(() => postMessages.interruptAsFork(fiberId)));
|
|
146
|
+
}), Effect__namespace.ensuring(semaphore.release(1)), Effect__namespace.fork)), Effect__namespace.forever, Effect__namespace.forkScoped);
|
|
141
147
|
const join = Effect__namespace.race(Fiber__namespace.joinAll([handleMessages, postMessages]), backing.join);
|
|
142
148
|
return {
|
|
143
149
|
id,
|
|
@@ -156,17 +162,25 @@ const layerManager$1 = /*#__PURE__*/Layer__namespace.effect(WorkerManager$1, mak
|
|
|
156
162
|
/** @internal */
|
|
157
163
|
const makePool$1 = () => options => Effect__namespace.gen(function* (_) {
|
|
158
164
|
const manager = yield* _(WorkerManager$1);
|
|
159
|
-
const
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
165
|
+
const workers = new Set();
|
|
166
|
+
const backing = yield* _(
|
|
167
|
+
// "timeToLive" in options ?
|
|
168
|
+
// Pool.makeWithTTL({
|
|
169
|
+
// acquire: manager.spawn<I, E, O>(options),
|
|
170
|
+
// min: options.minSize,
|
|
171
|
+
// max: options.maxSize,
|
|
172
|
+
// timeToLive: options.timeToLive
|
|
173
|
+
// }) :
|
|
174
|
+
Pool__namespace.make({
|
|
175
|
+
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),
|
|
166
176
|
size: options.size
|
|
167
177
|
}));
|
|
168
178
|
const pool = {
|
|
169
179
|
backing,
|
|
180
|
+
broadcast: message => Effect__namespace.forEach(workers, worker => worker.executeEffect(message), {
|
|
181
|
+
concurrency: "unbounded",
|
|
182
|
+
discard: true
|
|
183
|
+
}),
|
|
170
184
|
execute: message => Stream__namespace.unwrap(Effect__namespace.map(Effect__namespace.scoped(backing.get()), worker => worker.execute(message))),
|
|
171
185
|
executeEffect: message => Effect__namespace.flatMap(Effect__namespace.scoped(backing.get()), worker => worker.executeEffect(message))
|
|
172
186
|
};
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { Cause, Chunk } from 'effect';
|
|
2
|
+
import * as Channel from 'effect/Channel';
|
|
1
3
|
import * as Context from 'effect/Context';
|
|
2
4
|
import * as Deferred from 'effect/Deferred';
|
|
3
5
|
import * as Effect from 'effect/Effect';
|
|
4
6
|
import * as Exit from 'effect/Exit';
|
|
5
7
|
import * as Fiber from 'effect/Fiber';
|
|
6
|
-
import { pipe } from 'effect/Function';
|
|
8
|
+
import { pipe, identity } from 'effect/Function';
|
|
7
9
|
import * as Layer from 'effect/Layer';
|
|
8
10
|
import * as Pool from 'effect/Pool';
|
|
9
11
|
import * as Queue from 'effect/Queue';
|
|
@@ -43,7 +45,6 @@ const makeManager$1 = /*#__PURE__*/Effect.gen(function* (_) {
|
|
|
43
45
|
}) {
|
|
44
46
|
return Effect.gen(function* (_) {
|
|
45
47
|
const id = idCounter++;
|
|
46
|
-
const fiberId = yield* _(Effect.fiberId);
|
|
47
48
|
let requestIdCounter = 0;
|
|
48
49
|
const readyLatch = yield* _(Deferred.make());
|
|
49
50
|
const semaphore = yield* _(Effect.makeSemaphore(permits));
|
|
@@ -51,7 +52,7 @@ const makeManager$1 = /*#__PURE__*/Effect.gen(function* (_) {
|
|
|
51
52
|
const outbound = queue ?? (yield* _(defaultQueue()));
|
|
52
53
|
yield* _(Effect.addFinalizer(() => outbound.shutdown));
|
|
53
54
|
const backing = yield* _(platform.spawn(spawn(id)));
|
|
54
|
-
yield* _(Effect.addFinalizer(() => Effect.zipRight(Effect.forEach(requestMap.values(), ([queue]) => Queue.
|
|
55
|
+
yield* _(Effect.addFinalizer(() => Effect.zipRight(Effect.forEach(requestMap.values(), ([queue]) => Queue.offer(queue, Exit.failCause(Cause.empty)), {
|
|
55
56
|
discard: true
|
|
56
57
|
}), Effect.sync(() => requestMap.clear()))));
|
|
57
58
|
const handleMessage = msg => Effect.suspend(() => {
|
|
@@ -74,13 +75,13 @@ const makeManager$1 = /*#__PURE__*/Effect.gen(function* (_) {
|
|
|
74
75
|
// end
|
|
75
76
|
case 1:
|
|
76
77
|
{
|
|
77
|
-
return response.length === 2 ? Queue.
|
|
78
|
+
return response.length === 2 ? Queue.offer(queue[0], Exit.failCause(Cause.empty)) : Effect.zipRight(Queue.offer(queue[0], Exit.succeed(response[2])), Queue.offer(queue[0], Exit.failCause(Cause.empty)));
|
|
78
79
|
}
|
|
79
80
|
// error / defect
|
|
80
81
|
case 2:
|
|
81
82
|
case 3:
|
|
82
83
|
{
|
|
83
|
-
return
|
|
84
|
+
return Queue.offer(queue[0], response[1] === 2 ? Exit.fail(response[2]) : Exit.die(response[2]));
|
|
84
85
|
}
|
|
85
86
|
}
|
|
86
87
|
}
|
|
@@ -94,18 +95,22 @@ const makeManager$1 = /*#__PURE__*/Effect.gen(function* (_) {
|
|
|
94
95
|
const release = Effect.zipRight(Deferred.complete(deferred, Effect.unit), Effect.sync(() => requestMap.delete(id)));
|
|
95
96
|
return Exit.isInterrupted(exit) ? Effect.zipRight(backing.send([id, 1]), release) : release;
|
|
96
97
|
};
|
|
97
|
-
const execute = request => Stream.flatMap(Stream.acquireRelease(executeAcquire(request), executeRelease), ([, queue]) =>
|
|
98
|
+
const execute = request => Stream.flatMap(Stream.acquireRelease(executeAcquire(request), executeRelease), ([, queue]) => {
|
|
99
|
+
const loop = Channel.flatMap(Queue.take(queue), Exit.match({
|
|
100
|
+
onFailure: cause => Cause.isEmpty(cause) ? Channel.unit : Channel.failCause(cause),
|
|
101
|
+
onSuccess: value => Channel.flatMap(Channel.write(Chunk.of(value)), () => loop)
|
|
102
|
+
}));
|
|
103
|
+
return Stream.fromChannel(loop);
|
|
104
|
+
});
|
|
98
105
|
const executeEffect = request => Effect.acquireUseRelease(executeAcquire(request), ([, queue]) => Effect.flatten(Queue.take(queue)), executeRelease);
|
|
99
|
-
const handleMessages = yield* _(Queue.take(backing.queue), Effect.flatMap(handleMessage), Effect.forever, Effect.
|
|
100
|
-
yield* _(Effect.addFinalizer(() => handleMessages.interruptAsFork(fiberId)));
|
|
106
|
+
const handleMessages = yield* _(Queue.take(backing.queue), Effect.flatMap(handleMessage), Effect.forever, Effect.forkScoped);
|
|
101
107
|
const postMessages = yield* _(semaphore.take(1), Effect.zipRight(outbound.take), Effect.flatMap(([id, request]) => pipe(Effect.suspend(() => {
|
|
102
108
|
const result = requestMap.get(id);
|
|
103
109
|
if (!result) return Effect.unit;
|
|
104
110
|
const transferables = transfers(request);
|
|
105
111
|
const payload = encode ? encode(request) : request;
|
|
106
112
|
return Effect.zipRight(backing.send([id, 0, payload], transferables), Deferred.await(result[1]));
|
|
107
|
-
}), Effect.ensuring(semaphore.release(1)), Effect.fork)), Effect.forever, Effect.
|
|
108
|
-
yield* _(Effect.addFinalizer(() => postMessages.interruptAsFork(fiberId)));
|
|
113
|
+
}), Effect.ensuring(semaphore.release(1)), Effect.fork)), Effect.forever, Effect.forkScoped);
|
|
109
114
|
const join = Effect.race(Fiber.joinAll([handleMessages, postMessages]), backing.join);
|
|
110
115
|
return {
|
|
111
116
|
id,
|
|
@@ -124,17 +129,25 @@ const layerManager$1 = /*#__PURE__*/Layer.effect(WorkerManager$1, makeManager$1)
|
|
|
124
129
|
/** @internal */
|
|
125
130
|
const makePool$1 = () => options => Effect.gen(function* (_) {
|
|
126
131
|
const manager = yield* _(WorkerManager$1);
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
132
|
+
const workers = new Set();
|
|
133
|
+
const backing = yield* _(
|
|
134
|
+
// "timeToLive" in options ?
|
|
135
|
+
// Pool.makeWithTTL({
|
|
136
|
+
// acquire: manager.spawn<I, E, O>(options),
|
|
137
|
+
// min: options.minSize,
|
|
138
|
+
// max: options.maxSize,
|
|
139
|
+
// timeToLive: options.timeToLive
|
|
140
|
+
// }) :
|
|
141
|
+
Pool.make({
|
|
142
|
+
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),
|
|
134
143
|
size: options.size
|
|
135
144
|
}));
|
|
136
145
|
const pool = {
|
|
137
146
|
backing,
|
|
147
|
+
broadcast: message => Effect.forEach(workers, worker => worker.executeEffect(message), {
|
|
148
|
+
concurrency: "unbounded",
|
|
149
|
+
discard: true
|
|
150
|
+
}),
|
|
138
151
|
execute: message => Stream.unwrap(Effect.map(Effect.scoped(backing.get()), worker => worker.execute(message))),
|
|
139
152
|
executeEffect: message => Effect.flatMap(Effect.scoped(backing.get()), worker => worker.executeEffect(message))
|
|
140
153
|
};
|
|
@@ -3,7 +3,6 @@
|
|
|
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";
|
|
7
6
|
import type * as Layer from "effect/Layer";
|
|
8
7
|
import type * as Pool from "effect/Pool";
|
|
9
8
|
import type * as Queue from "effect/Queue";
|
|
@@ -96,6 +95,7 @@ export declare namespace Worker {
|
|
|
96
95
|
*/
|
|
97
96
|
export interface WorkerPool<I, E, O> {
|
|
98
97
|
readonly backing: Pool.Pool<WorkerError, Worker<I, E, O>>;
|
|
98
|
+
readonly broadcast: (message: I) => Effect.Effect<never, E | WorkerError, void>;
|
|
99
99
|
readonly execute: (message: I) => Stream.Stream<never, E | WorkerError, O>;
|
|
100
100
|
readonly executeEffect: (message: I) => Effect.Effect<never, E | WorkerError, O>;
|
|
101
101
|
}
|
|
@@ -109,11 +109,8 @@ export declare namespace WorkerPool {
|
|
|
109
109
|
* @category models
|
|
110
110
|
*/
|
|
111
111
|
type Options<I, W = unknown> = Worker.Options<I, W> & ({
|
|
112
|
+
readonly onCreate?: (worker: Worker<I, unknown, unknown>) => Effect.Effect<never, WorkerError, void>;
|
|
112
113
|
readonly size: number;
|
|
113
|
-
} | {
|
|
114
|
-
readonly minSize: number;
|
|
115
|
-
readonly maxSize: number;
|
|
116
|
-
readonly timeToLive: Duration.DurationInput;
|
|
117
114
|
});
|
|
118
115
|
}
|
|
119
116
|
/**
|
|
@@ -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,
|
|
1
|
+
{"version":3,"file":"Worker.d.ts","sourceRoot":"../../../src","sources":["Worker.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,7 +13,7 @@ import type { WorkerError } from "./WorkerError.js";
|
|
|
13
13
|
* @category models
|
|
14
14
|
*/
|
|
15
15
|
export interface BackingRunner<I, O> {
|
|
16
|
-
readonly fiber: Fiber.Fiber<WorkerError,
|
|
16
|
+
readonly fiber: Fiber.Fiber<WorkerError, never>;
|
|
17
17
|
readonly queue: Queue.Dequeue<I>;
|
|
18
18
|
readonly send: (message: O, transfers?: ReadonlyArray<unknown>) => Effect.Effect<never, never, void>;
|
|
19
19
|
}
|
|
@@ -69,5 +69,5 @@ export declare namespace Runner {
|
|
|
69
69
|
* @since 1.0.0
|
|
70
70
|
* @category constructors
|
|
71
71
|
*/
|
|
72
|
-
export declare const make: <I, R, E, O>(process: (request: I) => Stream.Stream<R, E, O> | Effect.Effect<R, E, O>, options?: Runner.Options<O> | undefined) => Effect.Effect<Scope.Scope | R | PlatformRunner, WorkerError,
|
|
72
|
+
export declare const make: <I, R, E, O>(process: (request: I) => Stream.Stream<R, E, O> | Effect.Effect<R, E, O>, options?: Runner.Options<O> | undefined) => Effect.Effect<Scope.Scope | R | PlatformRunner, WorkerError, never>;
|
|
73
73
|
//# sourceMappingURL=WorkerRunner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkerRunner.d.ts","sourceRoot":"../../../src","sources":["WorkerRunner.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,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,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"WorkerRunner.d.ts","sourceRoot":"../../../src","sources":["WorkerRunner.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,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,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,CAAA;IAC/C,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;IAChC,QAAQ,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC,EAAE,SAAS,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,CAAA;CACrG;AAED;;;GAGG;AACH,MAAM,CAAC,OAAO,WAAW,aAAa,CAAC;IACrC;;;OAGG;IACH,KAAY,OAAO,CAAC,CAAC,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;CACxE;AAED;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,OAAO,MAAsC,CAAA;AAEhF;;;GAGG;AACH,MAAM,MAAM,oBAAoB,GAAG,OAAO,oBAAoB,CAAA;AAE9D;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,CAAC,oBAAoB,CAAC,EAAE,oBAAoB,CAAA;IACrD,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;CACzF;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,cAAc,CAA2B,CAAA;AAElG;;;GAGG;AACH,MAAM,CAAC,OAAO,WAAW,MAAM,CAAC;IAC9B;;;OAGG;IACH,UAAiB,OAAO,CAAC,CAAC;QACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,OAAO,CAAA;QACzC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,aAAa,CAAC,OAAO,CAAC,CAAA;KAC5D;CACF;AAED;;;GAGG;AACH,eAAO,MAAM,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAC5B,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EACxE,OAAO,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,KACpC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,GAAG,cAAc,EAAE,WAAW,EAAE,KAAK,CAAiB,CAAA"}
|
package/package.json
CHANGED
package/src/Worker.ts
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
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"
|
|
7
6
|
import type * as Layer from "effect/Layer"
|
|
8
7
|
import type * as Pool from "effect/Pool"
|
|
9
8
|
import type * as Queue from "effect/Queue"
|
|
@@ -113,6 +112,7 @@ export declare namespace Worker {
|
|
|
113
112
|
*/
|
|
114
113
|
export interface WorkerPool<I, E, O> {
|
|
115
114
|
readonly backing: Pool.Pool<WorkerError, Worker<I, E, O>>
|
|
115
|
+
readonly broadcast: (message: I) => Effect.Effect<never, E | WorkerError, void>
|
|
116
116
|
readonly execute: (message: I) => Stream.Stream<never, E | WorkerError, O>
|
|
117
117
|
readonly executeEffect: (message: I) => Effect.Effect<never, E | WorkerError, O>
|
|
118
118
|
}
|
|
@@ -129,11 +129,12 @@ export declare namespace WorkerPool {
|
|
|
129
129
|
export type Options<I, W = unknown> =
|
|
130
130
|
& Worker.Options<I, W>
|
|
131
131
|
& ({
|
|
132
|
+
readonly onCreate?: (worker: Worker<I, unknown, unknown>) => Effect.Effect<never, WorkerError, void>
|
|
132
133
|
readonly size: number
|
|
133
|
-
|
|
134
|
-
readonly minSize: number
|
|
135
|
-
readonly maxSize: number
|
|
136
|
-
readonly timeToLive: Duration.DurationInput
|
|
134
|
+
// } | {
|
|
135
|
+
// readonly minSize: number
|
|
136
|
+
// readonly maxSize: number
|
|
137
|
+
// readonly timeToLive: Duration.DurationInput
|
|
137
138
|
})
|
|
138
139
|
}
|
|
139
140
|
|
package/src/WorkerRunner.ts
CHANGED
|
@@ -15,7 +15,7 @@ import type { WorkerError } from "./WorkerError"
|
|
|
15
15
|
* @category models
|
|
16
16
|
*/
|
|
17
17
|
export interface BackingRunner<I, O> {
|
|
18
|
-
readonly fiber: Fiber.Fiber<WorkerError,
|
|
18
|
+
readonly fiber: Fiber.Fiber<WorkerError, never>
|
|
19
19
|
readonly queue: Queue.Dequeue<I>
|
|
20
20
|
readonly send: (message: O, transfers?: ReadonlyArray<unknown>) => Effect.Effect<never, never, void>
|
|
21
21
|
}
|
|
@@ -81,4 +81,4 @@ export declare namespace Runner {
|
|
|
81
81
|
export const make: <I, R, E, O>(
|
|
82
82
|
process: (request: I) => Stream.Stream<R, E, O> | Effect.Effect<R, E, O>,
|
|
83
83
|
options?: Runner.Options<O> | undefined
|
|
84
|
-
) => Effect.Effect<Scope.Scope | R | PlatformRunner, WorkerError,
|
|
84
|
+
) => Effect.Effect<Scope.Scope | R | PlatformRunner, WorkerError, never> = internal.make
|
package/src/internal/worker.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { Cause, Chunk } from "effect"
|
|
2
|
+
import * as Channel from "effect/Channel"
|
|
1
3
|
import * as Context from "effect/Context"
|
|
2
4
|
import * as Deferred from "effect/Deferred"
|
|
3
5
|
import * as Effect from "effect/Effect"
|
|
4
6
|
import * as Exit from "effect/Exit"
|
|
5
7
|
import * as Fiber from "effect/Fiber"
|
|
6
|
-
import { pipe } from "effect/Function"
|
|
8
|
+
import { identity, pipe } from "effect/Function"
|
|
7
9
|
import * as Layer from "effect/Layer"
|
|
8
10
|
import * as Pool from "effect/Pool"
|
|
9
11
|
import * as Queue from "effect/Queue"
|
|
@@ -51,7 +53,6 @@ export const makeManager = Effect.gen(function*(_) {
|
|
|
51
53
|
spawn<I, E, O>({ encode, permits = 1, queue, spawn, transfers = (_) => [] }: Worker.Worker.Options<I>) {
|
|
52
54
|
return Effect.gen(function*(_) {
|
|
53
55
|
const id = idCounter++
|
|
54
|
-
const fiberId = yield* _(Effect.fiberId)
|
|
55
56
|
let requestIdCounter = 0
|
|
56
57
|
const readyLatch = yield* _(Deferred.make<never, void>())
|
|
57
58
|
const semaphore = yield* _(Effect.makeSemaphore(permits))
|
|
@@ -66,7 +67,9 @@ export const makeManager = Effect.gen(function*(_) {
|
|
|
66
67
|
|
|
67
68
|
yield* _(Effect.addFinalizer(() =>
|
|
68
69
|
Effect.zipRight(
|
|
69
|
-
Effect.forEach(requestMap.values(), ([queue]) => Queue.
|
|
70
|
+
Effect.forEach(requestMap.values(), ([queue]) => Queue.offer(queue, Exit.failCause(Cause.empty)), {
|
|
71
|
+
discard: true
|
|
72
|
+
}),
|
|
70
73
|
Effect.sync(() => requestMap.clear())
|
|
71
74
|
)
|
|
72
75
|
))
|
|
@@ -90,23 +93,20 @@ export const makeManager = Effect.gen(function*(_) {
|
|
|
90
93
|
// end
|
|
91
94
|
case 1: {
|
|
92
95
|
return response.length === 2 ?
|
|
93
|
-
Queue.
|
|
96
|
+
Queue.offer(queue[0], Exit.failCause(Cause.empty)) :
|
|
94
97
|
Effect.zipRight(
|
|
95
98
|
Queue.offer(queue[0], Exit.succeed(response[2])),
|
|
96
|
-
Queue.
|
|
99
|
+
Queue.offer(queue[0], Exit.failCause(Cause.empty))
|
|
97
100
|
)
|
|
98
101
|
}
|
|
99
102
|
// error / defect
|
|
100
103
|
case 2:
|
|
101
104
|
case 3: {
|
|
102
|
-
return
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
response[
|
|
106
|
-
|
|
107
|
-
: Exit.die(response[2])
|
|
108
|
-
),
|
|
109
|
-
Queue.shutdown(queue[0])
|
|
105
|
+
return Queue.offer(
|
|
106
|
+
queue[0],
|
|
107
|
+
response[1] === 2
|
|
108
|
+
? Exit.fail(response[2])
|
|
109
|
+
: Exit.die(response[2])
|
|
110
110
|
)
|
|
111
111
|
}
|
|
112
112
|
}
|
|
@@ -150,7 +150,16 @@ export const makeManager = Effect.gen(function*(_) {
|
|
|
150
150
|
executeAcquire(request),
|
|
151
151
|
executeRelease
|
|
152
152
|
),
|
|
153
|
-
([, queue]) =>
|
|
153
|
+
([, queue]) => {
|
|
154
|
+
const loop: Channel.Channel<never, unknown, unknown, unknown, E, Chunk.Chunk<O>, void> = Channel.flatMap(
|
|
155
|
+
Queue.take(queue),
|
|
156
|
+
Exit.match({
|
|
157
|
+
onFailure: (cause) => Cause.isEmpty(cause) ? Channel.unit : Channel.failCause(cause),
|
|
158
|
+
onSuccess: (value) => Channel.flatMap(Channel.write(Chunk.of(value)), () => loop)
|
|
159
|
+
})
|
|
160
|
+
)
|
|
161
|
+
return Stream.fromChannel(loop)
|
|
162
|
+
}
|
|
154
163
|
)
|
|
155
164
|
|
|
156
165
|
const executeEffect = (request: I) =>
|
|
@@ -164,9 +173,8 @@ export const makeManager = Effect.gen(function*(_) {
|
|
|
164
173
|
Queue.take(backing.queue),
|
|
165
174
|
Effect.flatMap(handleMessage),
|
|
166
175
|
Effect.forever,
|
|
167
|
-
Effect.
|
|
176
|
+
Effect.forkScoped
|
|
168
177
|
)
|
|
169
|
-
yield* _(Effect.addFinalizer(() => handleMessages.interruptAsFork(fiberId)))
|
|
170
178
|
|
|
171
179
|
const postMessages = yield* _(
|
|
172
180
|
semaphore.take(1),
|
|
@@ -188,9 +196,8 @@ export const makeManager = Effect.gen(function*(_) {
|
|
|
188
196
|
)
|
|
189
197
|
),
|
|
190
198
|
Effect.forever,
|
|
191
|
-
Effect.
|
|
199
|
+
Effect.forkScoped
|
|
192
200
|
)
|
|
193
|
-
yield* _(Effect.addFinalizer(() => postMessages.interruptAsFork(fiberId)))
|
|
194
201
|
|
|
195
202
|
const join = Effect.race(
|
|
196
203
|
Fiber.joinAll([
|
|
@@ -216,21 +223,32 @@ export const makePool = <W>() =>
|
|
|
216
223
|
) =>
|
|
217
224
|
Effect.gen(function*(_) {
|
|
218
225
|
const manager = yield* _(WorkerManager)
|
|
226
|
+
const workers = new Set<Worker.Worker<I, E, O>>()
|
|
219
227
|
const backing = yield* _(
|
|
220
|
-
"timeToLive" in options ?
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
228
|
+
// "timeToLive" in options ?
|
|
229
|
+
// Pool.makeWithTTL({
|
|
230
|
+
// acquire: manager.spawn<I, E, O>(options),
|
|
231
|
+
// min: options.minSize,
|
|
232
|
+
// max: options.maxSize,
|
|
233
|
+
// timeToLive: options.timeToLive
|
|
234
|
+
// }) :
|
|
235
|
+
Pool.make({
|
|
236
|
+
acquire: pipe(
|
|
237
|
+
manager.spawn<I, E, O>(options),
|
|
238
|
+
Effect.tap((worker) => Effect.sync(() => workers.add(worker))),
|
|
239
|
+
Effect.tap((worker) => Effect.addFinalizer(() => Effect.sync(() => workers.delete(worker)))),
|
|
240
|
+
options.onCreate ? Effect.tap(options.onCreate) : identity
|
|
241
|
+
),
|
|
242
|
+
size: options.size
|
|
243
|
+
})
|
|
231
244
|
)
|
|
232
245
|
const pool: Worker.WorkerPool<I, E, O> = {
|
|
233
246
|
backing,
|
|
247
|
+
broadcast: (message: I) =>
|
|
248
|
+
Effect.forEach(workers, (worker) => worker.executeEffect(message), {
|
|
249
|
+
concurrency: "unbounded",
|
|
250
|
+
discard: true
|
|
251
|
+
}),
|
|
234
252
|
execute: (message: I) =>
|
|
235
253
|
Stream.unwrap(
|
|
236
254
|
Effect.map(
|
|
@@ -7,6 +7,7 @@ import { pipe } from "effect/Function"
|
|
|
7
7
|
import * as Queue from "effect/Queue"
|
|
8
8
|
import * as Stream from "effect/Stream"
|
|
9
9
|
import type * as Worker from "../Worker"
|
|
10
|
+
import type * as WorkerError from "../WorkerError"
|
|
10
11
|
import type * as WorkerRunner from "../WorkerRunner"
|
|
11
12
|
|
|
12
13
|
/** @internal */
|
|
@@ -86,6 +87,6 @@ export const make = <I, R, E, O>(
|
|
|
86
87
|
Effect.all([
|
|
87
88
|
handleRequests,
|
|
88
89
|
Fiber.join(backing.fiber)
|
|
89
|
-
], { concurrency: "unbounded", discard: true })
|
|
90
|
+
], { concurrency: "unbounded", discard: true }) as Effect.Effect<R, WorkerError.WorkerError, never>
|
|
90
91
|
)
|
|
91
92
|
})
|