knitting 0.1.50 → 0.1.52
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/README.md +268 -75
- package/knitting.d.ts +1 -0
- package/map.md +56 -6
- package/package.json +16 -4
- package/prebuilds/darwin-arm64-node-127/knitting_buffer_pointer.node +0 -0
- package/prebuilds/darwin-arm64-node-127/knitting_shared_memory.node +0 -0
- package/prebuilds/darwin-arm64-node-137/knitting_buffer_pointer.node +0 -0
- package/prebuilds/darwin-arm64-node-137/knitting_shared_memory.node +0 -0
- package/prebuilds/darwin-x64-node-127/knitting_buffer_pointer.node +0 -0
- package/prebuilds/darwin-x64-node-127/knitting_shared_memory.node +0 -0
- package/prebuilds/darwin-x64-node-137/knitting_buffer_pointer.node +0 -0
- package/prebuilds/darwin-x64-node-137/knitting_shared_memory.node +0 -0
- package/prebuilds/linux-x64-node-127/knitting_buffer_pointer.node +0 -0
- package/prebuilds/linux-x64-node-127/knitting_shared_memory.node +0 -0
- package/prebuilds/linux-x64-node-137/knitting_buffer_pointer.node +0 -0
- package/prebuilds/linux-x64-node-137/knitting_shared_memory.node +0 -0
- package/prebuilds/win32-x64/knitting_windows_shared_memory.dll +0 -0
- package/prebuilds/win32-x64-node-127/knitting_buffer_pointer.node +0 -0
- package/prebuilds/win32-x64-node-127/knitting_shared_memory.node +0 -0
- package/prebuilds/win32-x64-node-127/knitting_shm.node +0 -0
- package/prebuilds/win32-x64-node-137/knitting_buffer_pointer.node +0 -0
- package/prebuilds/win32-x64-node-137/knitting_shared_memory.node +0 -0
- package/prebuilds/win32-x64-node-137/knitting_shm.node +0 -0
- package/scripts/build-native-addons.ts +5 -0
- package/src/api.d.ts +5 -11
- package/src/api.js +103 -22
- package/src/common/envelope.d.ts +9 -3
- package/src/common/envelope.js +14 -0
- package/src/common/task-source.js +4 -0
- package/src/common/worker-runtime.d.ts +2 -0
- package/src/common/worker-runtime.js +9 -0
- package/src/connections/buffer-reference-native.d.ts +56 -0
- package/src/connections/buffer-reference-native.js +217 -0
- package/src/connections/buffer-reference.d.ts +76 -0
- package/src/connections/buffer-reference.js +459 -0
- package/src/connections/index.d.ts +1 -0
- package/src/connections/index.js +1 -0
- package/src/connections/node-addons.d.ts +1 -1
- package/src/connections/node-buffer-pointer.d.ts +20 -0
- package/src/connections/node-buffer-pointer.js +16 -0
- package/src/connections/process-shared-buffer.js +2 -0
- package/src/connections/shared-array-buffer-payload.d.ts +36 -0
- package/src/connections/shared-array-buffer-payload.js +235 -0
- package/src/knitting_buffer_pointer.cc +425 -0
- package/src/knitting_shared_memory.cc +9 -2
- package/src/memory/lock.d.ts +12 -1
- package/src/memory/lock.js +55 -172
- package/src/memory/payloadCodec.js +241 -65
- package/src/memory/shared-buffer-io.d.ts +2 -0
- package/src/memory/shared-buffer-io.js +23 -0
- package/src/runtime/inline-executor.d.ts +2 -2
- package/src/runtime/inline-executor.js +15 -3
- package/src/runtime/pool.d.ts +3 -1
- package/src/runtime/pool.js +9 -1
- package/src/runtime/process-worker.js +3 -1
- package/src/runtime/tx-queue.d.ts +3 -2
- package/src/runtime/tx-queue.js +18 -13
- package/src/types.d.ts +39 -18
- package/src/utils/http.d.ts +21 -0
- package/src/utils/http.js +93 -0
- package/src/worker/loop.js +26 -4
- package/src/worker/process-worker-bootstrap.js +1 -0
- package/src/worker/rx-queue.d.ts +4 -1
- package/src/worker/rx-queue.js +53 -4
- package/src/worker/safety/startup.d.ts +2 -1
- package/src/worker/safety/startup.js +5 -2
- package/src/worker/task-loader.d.ts +2 -1
- package/src/worker/task-loader.js +14 -2
- package/unsafe.d.ts +1 -0
- package/unsafe.js +1 -0
- package/utils.d.ts +1 -0
- package/utils.js +1 -0
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { beginPromisePayload, finishPromisePayload, getTaskSlotIndex, HEADER_BYTE_LENGTH, HEADER_SLOT_STRIDE_U32, HEADER_STATIC_PAYLOAD_U32, LockBound, PayloadBuffer, PayloadSignal, TaskIndex, } from "./lock.js";
|
|
1
|
+
import { attachPayloadTransportFinalizer, beginPromisePayload, finishPromisePayload, getTaskSlotIndex, HEADER_BYTE_LENGTH, HEADER_SLOT_STRIDE_U32, HEADER_STATIC_PAYLOAD_U32, LockBound, PayloadBuffer, PayloadSignal, TaskIndex, } from "./lock.js";
|
|
2
2
|
import { register } from "./regionRegistry.js";
|
|
3
3
|
import { createSharedDynamicBufferIO, createSharedStaticBufferIO, } from "./shared-buffer-io.js";
|
|
4
4
|
import { getStridedRegionSpanBytes } from "./byte-carpet.js";
|
|
5
5
|
import { encoderError, ErrorKnitting } from "../error.js";
|
|
6
6
|
import { Envelope } from "../common/envelope.js";
|
|
7
7
|
import { resolvePayloadBufferOptions, } from "./payload-config.js";
|
|
8
|
+
import { getSharedArrayBufferPayload, SHARED_ARRAY_BUFFER_CODEC_ID, SHARED_ARRAY_BUFFER_NUMERIC_TRANSFER, SHARED_ARRAY_BUFFER_NUMERIC_WORDS, } from "../connections/shared-array-buffer-payload.js";
|
|
9
|
+
const BUFFER_REFERENCE_NUMERIC_TRANSFER = Symbol.for("knitting.bufferReference.numericTransfer");
|
|
8
10
|
const memory = new ArrayBuffer(8);
|
|
9
11
|
const Float64View = new Float64Array(memory);
|
|
10
12
|
const BigInt64View = new BigInt64Array(memory);
|
|
@@ -28,6 +30,7 @@ const BIGINT64_MAX = (1n << 63n) - 1n;
|
|
|
28
30
|
const { parse: parseJSON, stringify: stringifyJSON } = JSON;
|
|
29
31
|
const { for: symbolFor, keyFor: symbolKeyFor } = Symbol;
|
|
30
32
|
const EXTERNAL_PAYLOAD_BRAND = symbolFor("knitting.payloadCodec");
|
|
33
|
+
const BUFFER_REFERENCE_CODEC_ID = "knitting.bufferReference";
|
|
31
34
|
const PROCESS_SHARED_BUFFER_CODEC_ID = "knitting.processSharedBuffer";
|
|
32
35
|
const externalPayloadGlobal = globalThis;
|
|
33
36
|
const objectGetPrototypeOf = Object.getPrototypeOf;
|
|
@@ -35,7 +38,8 @@ const objectHasOwn = Object.prototype.hasOwnProperty;
|
|
|
35
38
|
const arrayIsArray = Array.isArray;
|
|
36
39
|
const objectPrototype = Object.prototype;
|
|
37
40
|
const UNSUPPORTED_OBJECT_DETAIL = "Unsupported object type. Allowed: plain object, array, Error, Date, Envelope, Buffer, ArrayBuffer, DataView, typed arrays, and registered external payloads. Serialize it yourself.";
|
|
38
|
-
const ENVELOPE_PAYLOAD_DETAIL = "Envelope payload must be an ArrayBuffer
|
|
41
|
+
const ENVELOPE_PAYLOAD_DETAIL = "Envelope payload must be an ArrayBuffer, SharedArrayBuffer, " +
|
|
42
|
+
"ProcessSharedBuffer, or BufferReference.";
|
|
39
43
|
const ENVELOPE_HEADER_DETAIL = "Envelope header must be a JSON-like value or string.";
|
|
40
44
|
const ENVELOPE_PROMISE_DETAIL = "Envelope header cannot contain Promise values.";
|
|
41
45
|
const DYNAMIC_PAYLOAD_LIMIT_DETAIL = "Dynamic payload exceeds maxPayloadBytes.";
|
|
@@ -92,23 +96,18 @@ const decodeExternalPayload = (raw) => {
|
|
|
92
96
|
: { codec: codecId, metadata };
|
|
93
97
|
};
|
|
94
98
|
const PROCESS_SHARED_BUFFER_NUMERIC_WORDS = 8;
|
|
95
|
-
const
|
|
99
|
+
const BUFFER_REFERENCE_NUMERIC_WORDS = 8;
|
|
96
100
|
const NUMERIC_SENTINEL = 0xffffffff;
|
|
97
|
-
const
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
out[i] = view.getUint32(i * Uint32Array.BYTES_PER_ELEMENT, true);
|
|
101
|
+
const decodeNumericExternalPayload = (codecId, words) => {
|
|
102
|
+
const codec = externalPayloadGlobal.__KNITTING_PAYLOAD_CODECS__?.[codecId];
|
|
103
|
+
if (typeof codec?.decodeNumeric === "function") {
|
|
104
|
+
return codec.decodeNumeric(words);
|
|
102
105
|
}
|
|
103
|
-
return
|
|
104
|
-
};
|
|
105
|
-
const decodeProcessSharedBufferNumeric = (bytes) => {
|
|
106
|
-
const metadata = readProcessSharedBufferNumericPayload(bytes);
|
|
107
|
-
const codec = externalPayloadGlobal.__KNITTING_PAYLOAD_CODECS__?.[PROCESS_SHARED_BUFFER_CODEC_ID];
|
|
108
|
-
return typeof codec?.decodeNumeric === "function"
|
|
109
|
-
? codec.decodeNumeric(metadata)
|
|
110
|
-
: { codec: PROCESS_SHARED_BUFFER_CODEC_ID, metadata };
|
|
106
|
+
return { codec: codecId, metadata: Array.from(words) };
|
|
111
107
|
};
|
|
108
|
+
const decodeProcessSharedBufferNumericWords = (words) => decodeNumericExternalPayload(PROCESS_SHARED_BUFFER_CODEC_ID, words);
|
|
109
|
+
const decodeBufferReferenceNumericWords = (words) => decodeNumericExternalPayload(BUFFER_REFERENCE_CODEC_ID, words);
|
|
110
|
+
const decodeSharedArrayBufferNumericWords = (words) => decodeNumericExternalPayload(SHARED_ARRAY_BUFFER_CODEC_ID, words);
|
|
112
111
|
const tryEncodePrimitiveTask = (task) => {
|
|
113
112
|
const value = task.value;
|
|
114
113
|
switch (typeof value) {
|
|
@@ -299,7 +298,7 @@ export const encodePayload = ({ lockSector, payload, sab, payloadConfig, headers
|
|
|
299
298
|
payloadConfig: resolvedPayloadConfig,
|
|
300
299
|
textCompat: textCompat?.payload,
|
|
301
300
|
});
|
|
302
|
-
const { maxBytes: staticMaxBytes, writeBinary: writeStaticBinary, writeBuffer: writeStaticBuffer, writeArrayBuffer: writeStaticArrayBuffer, writeExactUint8Array: writeStaticExactUint8Array, write8Binary: writeStatic8Binary, writeUtf8: writeStaticUtf8, } = requireStaticIO(headersBuffer, headerSlotStrideU32, textCompat?.headers);
|
|
301
|
+
const { maxBytes: staticMaxBytes, writeBinary: writeStaticBinary, writeBuffer: writeStaticBuffer, writeArrayBuffer: writeStaticArrayBuffer, writeExactUint8Array: writeStaticExactUint8Array, writeU32Words: writeStaticU32Words, write8Binary: writeStatic8Binary, writeUtf8: writeStaticUtf8, } = requireStaticIO(headersBuffer, headerSlotStrideU32, textCompat?.headers);
|
|
303
302
|
const dynamicLimitError = (task, actualBytes, label) => encoderError({
|
|
304
303
|
task,
|
|
305
304
|
type: ErrorKnitting.Serializable,
|
|
@@ -523,11 +522,8 @@ export const encodePayload = ({ lockSector, payload, sab, payloadConfig, headers
|
|
|
523
522
|
task.value = null;
|
|
524
523
|
return true;
|
|
525
524
|
};
|
|
526
|
-
const
|
|
527
|
-
const
|
|
528
|
-
const writeProcessSharedBufferWord = (index, value) => {
|
|
529
|
-
processSharedBufferScratchView.setUint32(index * Uint32Array.BYTES_PER_ELEMENT, value, true);
|
|
530
|
-
};
|
|
525
|
+
const processSharedBufferWords = new Uint32Array(PROCESS_SHARED_BUFFER_NUMERIC_WORDS);
|
|
526
|
+
const sharedArrayBufferWords = new Uint32Array(SHARED_ARRAY_BUFFER_NUMERIC_WORDS);
|
|
531
527
|
const tryEncodeProcessSharedBufferNumeric = (task, slotIndex, value) => {
|
|
532
528
|
const descriptor = value.descriptor;
|
|
533
529
|
if (descriptor === undefined ||
|
|
@@ -544,19 +540,47 @@ export const encodePayload = ({ lockSector, payload, sab, payloadConfig, headers
|
|
|
544
540
|
!isU32(baseAddressMod64)) {
|
|
545
541
|
return false;
|
|
546
542
|
}
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
return false;
|
|
543
|
+
processSharedBufferWords[0] = descriptor.fd;
|
|
544
|
+
processSharedBufferWords[1] = descriptor.size;
|
|
545
|
+
processSharedBufferWords[2] = descriptor.byteLength;
|
|
546
|
+
processSharedBufferWords[3] = value.byteOffset;
|
|
547
|
+
processSharedBufferWords[4] = value.byteLength;
|
|
548
|
+
processSharedBufferWords[5] = runtimeCode(descriptor.runtime);
|
|
549
|
+
processSharedBufferWords[6] = kindCode(descriptor.kind);
|
|
550
|
+
processSharedBufferWords[7] = baseAddressMod64 === undefined
|
|
551
|
+
? NUMERIC_SENTINEL
|
|
552
|
+
: baseAddressMod64;
|
|
558
553
|
task[TaskIndex.Type] = PayloadBuffer.ProcessSharedBuffer;
|
|
559
|
-
|
|
554
|
+
// Static region is a Uint32Array shared in-process; write the descriptor
|
|
555
|
+
// words straight in instead of staging bytes through a DataView + copy.
|
|
556
|
+
task[TaskIndex.PayloadLen] = writeStaticU32Words(processSharedBufferWords, PROCESS_SHARED_BUFFER_NUMERIC_WORDS, slotIndex);
|
|
557
|
+
task.value = null;
|
|
558
|
+
return true;
|
|
559
|
+
};
|
|
560
|
+
const tryEncodeBufferReferenceNumeric = (task, slotIndex, value) => {
|
|
561
|
+
const words = value[BUFFER_REFERENCE_NUMERIC_TRANSFER]?.();
|
|
562
|
+
if (words === undefined)
|
|
563
|
+
return false;
|
|
564
|
+
task[TaskIndex.Type] = PayloadBuffer.BufferReference;
|
|
565
|
+
task[TaskIndex.PayloadLen] = writeStaticU32Words(words, BUFFER_REFERENCE_NUMERIC_WORDS, slotIndex);
|
|
566
|
+
attachPayloadTransportFinalizer(task, value);
|
|
567
|
+
task.value = null;
|
|
568
|
+
return true;
|
|
569
|
+
};
|
|
570
|
+
const tryEncodeSharedArrayBufferNumeric = (task, slotIndex, value) => {
|
|
571
|
+
const words = value[SHARED_ARRAY_BUFFER_NUMERIC_TRANSFER]?.(lockSector);
|
|
572
|
+
if (words === undefined)
|
|
573
|
+
return false;
|
|
574
|
+
sharedArrayBufferWords[0] = words[0] ?? 0;
|
|
575
|
+
sharedArrayBufferWords[1] = words[1] ?? 0;
|
|
576
|
+
sharedArrayBufferWords[2] = words[2] ?? 0;
|
|
577
|
+
sharedArrayBufferWords[3] = words[3] ?? 0;
|
|
578
|
+
sharedArrayBufferWords[4] = words[4] ?? 0;
|
|
579
|
+
sharedArrayBufferWords[5] = words[5] ?? 0;
|
|
580
|
+
sharedArrayBufferWords[6] = words[6] ?? 0;
|
|
581
|
+
sharedArrayBufferWords[7] = words[7] ?? 0;
|
|
582
|
+
task[TaskIndex.Type] = PayloadBuffer.SharedArrayBuffer;
|
|
583
|
+
task[TaskIndex.PayloadLen] = writeStaticU32Words(sharedArrayBufferWords, words.length, slotIndex);
|
|
560
584
|
task.value = null;
|
|
561
585
|
return true;
|
|
562
586
|
};
|
|
@@ -570,6 +594,14 @@ export const encodePayload = ({ lockSector, payload, sab, payloadConfig, headers
|
|
|
570
594
|
detail: UNSUPPORTED_OBJECT_DETAIL,
|
|
571
595
|
});
|
|
572
596
|
}
|
|
597
|
+
if (codecId === SHARED_ARRAY_BUFFER_CODEC_ID &&
|
|
598
|
+
tryEncodeSharedArrayBufferNumeric(task, slotIndex, externalPayload)) {
|
|
599
|
+
return true;
|
|
600
|
+
}
|
|
601
|
+
if (codecId === BUFFER_REFERENCE_CODEC_ID &&
|
|
602
|
+
tryEncodeBufferReferenceNumeric(task, slotIndex, externalPayload)) {
|
|
603
|
+
return true;
|
|
604
|
+
}
|
|
573
605
|
if (codecId === PROCESS_SHARED_BUFFER_CODEC_ID &&
|
|
574
606
|
tryEncodeProcessSharedBufferNumeric(task, slotIndex, externalPayload)) {
|
|
575
607
|
return true;
|
|
@@ -600,6 +632,7 @@ export const encodePayload = ({ lockSector, payload, sab, payloadConfig, headers
|
|
|
600
632
|
if (written !== -1) {
|
|
601
633
|
task[TaskIndex.Type] = PayloadBuffer.StaticExternalPayload;
|
|
602
634
|
task[TaskIndex.PayloadLen] = written;
|
|
635
|
+
attachPayloadTransportFinalizer(task, externalPayload);
|
|
603
636
|
task.value = null;
|
|
604
637
|
return true;
|
|
605
638
|
}
|
|
@@ -614,6 +647,7 @@ export const encodePayload = ({ lockSector, payload, sab, payloadConfig, headers
|
|
|
614
647
|
return failDynamicWriteAfterReserve(task, reservedSlot);
|
|
615
648
|
task[TaskIndex.PayloadLen] = written;
|
|
616
649
|
setSlotLength(reservedSlot, written);
|
|
650
|
+
attachPayloadTransportFinalizer(task, externalPayload);
|
|
617
651
|
task.value = null;
|
|
618
652
|
return true;
|
|
619
653
|
};
|
|
@@ -625,52 +659,50 @@ export const encodePayload = ({ lockSector, payload, sab, payloadConfig, headers
|
|
|
625
659
|
task.value = null;
|
|
626
660
|
return true;
|
|
627
661
|
};
|
|
628
|
-
const
|
|
629
|
-
const header = envelope.header;
|
|
630
|
-
const payload = envelope.payload;
|
|
631
|
-
const headerIsString = typeof header === "string";
|
|
632
|
-
if (!(payload instanceof ArrayBuffer)) {
|
|
633
|
-
return encoderError({
|
|
634
|
-
task,
|
|
635
|
-
type: ErrorKnitting.Serializable,
|
|
636
|
-
onPromise,
|
|
637
|
-
detail: ENVELOPE_PAYLOAD_DETAIL,
|
|
638
|
-
});
|
|
639
|
-
}
|
|
662
|
+
const encodeEnvelopeHeaderText = (task, header, headerIsString) => {
|
|
640
663
|
if (hasPromiseInEnvelopeHeader(header)) {
|
|
641
|
-
|
|
664
|
+
encoderError({
|
|
642
665
|
task,
|
|
643
666
|
type: ErrorKnitting.Serializable,
|
|
644
667
|
onPromise,
|
|
645
668
|
detail: ENVELOPE_PROMISE_DETAIL,
|
|
646
669
|
});
|
|
670
|
+
return undefined;
|
|
647
671
|
}
|
|
672
|
+
if (headerIsString)
|
|
673
|
+
return header;
|
|
648
674
|
let headerText;
|
|
649
|
-
|
|
650
|
-
headerText = header;
|
|
675
|
+
try {
|
|
676
|
+
headerText = stringifyJSON(header);
|
|
651
677
|
}
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
catch (error) {
|
|
657
|
-
const detail = error instanceof Error ? error.message : String(error);
|
|
658
|
-
return encoderError({
|
|
659
|
-
task,
|
|
660
|
-
type: ErrorKnitting.Json,
|
|
661
|
-
onPromise,
|
|
662
|
-
detail,
|
|
663
|
-
});
|
|
664
|
-
}
|
|
678
|
+
catch (error) {
|
|
679
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
680
|
+
encoderError({ task, type: ErrorKnitting.Json, onPromise, detail });
|
|
681
|
+
return undefined;
|
|
665
682
|
}
|
|
666
683
|
if (typeof headerText !== "string") {
|
|
667
|
-
|
|
684
|
+
encoderError({
|
|
668
685
|
task,
|
|
669
686
|
type: ErrorKnitting.Serializable,
|
|
670
687
|
onPromise,
|
|
671
688
|
detail: ENVELOPE_HEADER_DETAIL,
|
|
672
689
|
});
|
|
690
|
+
return undefined;
|
|
691
|
+
}
|
|
692
|
+
return headerText;
|
|
693
|
+
};
|
|
694
|
+
const resolveEnvelopeExternalBody = (body) => {
|
|
695
|
+
if (body === null || typeof body !== "object")
|
|
696
|
+
return undefined;
|
|
697
|
+
const sharedArrayBuffer = getSharedArrayBufferPayload(body);
|
|
698
|
+
if (sharedArrayBuffer !== undefined)
|
|
699
|
+
return sharedArrayBuffer;
|
|
700
|
+
if (isExternalPayloadLike(body)) {
|
|
701
|
+
return body;
|
|
673
702
|
}
|
|
703
|
+
return undefined;
|
|
704
|
+
};
|
|
705
|
+
const encodeEnvelopeArrayBufferBody = (task, slotIndex, headerText, headerIsString, payload) => {
|
|
674
706
|
const payloadBytes = new Uint8Array(payload);
|
|
675
707
|
const payloadLength = payloadBytes.byteLength;
|
|
676
708
|
const payloadReserveBytes = payloadLength > 0 ? payloadLength : 1;
|
|
@@ -718,6 +750,107 @@ export const encodePayload = ({ lockSector, payload, sab, payloadConfig, headers
|
|
|
718
750
|
task.value = null;
|
|
719
751
|
return true;
|
|
720
752
|
};
|
|
753
|
+
const encodeEnvelopeExternalBody = (task, slotIndex, headerText, headerIsString, externalBody) => {
|
|
754
|
+
const codecId = readExternalPayloadCodecId(externalBody);
|
|
755
|
+
if (codecId === undefined) {
|
|
756
|
+
return encoderError({
|
|
757
|
+
task,
|
|
758
|
+
type: ErrorKnitting.Serializable,
|
|
759
|
+
onPromise,
|
|
760
|
+
detail: ENVELOPE_PAYLOAD_DETAIL,
|
|
761
|
+
});
|
|
762
|
+
}
|
|
763
|
+
let bodyText;
|
|
764
|
+
try {
|
|
765
|
+
bodyText = stringifyJSON([codecId, externalBody.toMetadata()]);
|
|
766
|
+
}
|
|
767
|
+
catch (error) {
|
|
768
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
769
|
+
return encoderError({
|
|
770
|
+
task,
|
|
771
|
+
type: ErrorKnitting.Serializable,
|
|
772
|
+
onPromise,
|
|
773
|
+
detail,
|
|
774
|
+
});
|
|
775
|
+
}
|
|
776
|
+
if (typeof bodyText !== "string") {
|
|
777
|
+
return encoderError({
|
|
778
|
+
task,
|
|
779
|
+
type: ErrorKnitting.Serializable,
|
|
780
|
+
onPromise,
|
|
781
|
+
detail: "Envelope body metadata must be JSON serializable.",
|
|
782
|
+
});
|
|
783
|
+
}
|
|
784
|
+
const bodyBytes = textEncode.encode(bodyText);
|
|
785
|
+
const bodyLength = bodyBytes.byteLength;
|
|
786
|
+
const staticHeaderWritten = writeStaticUtf8(headerText, slotIndex);
|
|
787
|
+
if (staticHeaderWritten !== -1) {
|
|
788
|
+
if (!ensureWithinDynamicLimit(task, bodyLength, "EnvelopeStaticHeaderExternal"))
|
|
789
|
+
return false;
|
|
790
|
+
const reservedSlot = reserveDynamicObject(task, bodyLength);
|
|
791
|
+
task[TaskIndex.Type] = headerIsString
|
|
792
|
+
? PayloadBuffer.EnvelopeStaticHeaderStringExternal
|
|
793
|
+
: PayloadBuffer.EnvelopeStaticHeaderExternal;
|
|
794
|
+
task[TaskIndex.PayloadLen] = staticHeaderWritten;
|
|
795
|
+
task[TaskIndex.End] = bodyLength;
|
|
796
|
+
const bodyWritten = writeDynamicBinary(bodyBytes, task[TaskIndex.Start]);
|
|
797
|
+
if (bodyWritten < 0) {
|
|
798
|
+
return failDynamicWriteAfterReserve(task, reservedSlot);
|
|
799
|
+
}
|
|
800
|
+
setSlotLength(reservedSlot, bodyWritten);
|
|
801
|
+
attachPayloadTransportFinalizer(task, externalBody);
|
|
802
|
+
task.value = null;
|
|
803
|
+
return true;
|
|
804
|
+
}
|
|
805
|
+
const headerReserveBytes = dynamicUtf8ReserveBytesWithExtra(task, headerText, bodyLength, headerIsString
|
|
806
|
+
? "EnvelopeDynamicHeaderStringExternal"
|
|
807
|
+
: "EnvelopeDynamicHeaderExternal");
|
|
808
|
+
if (headerReserveBytes < 0)
|
|
809
|
+
return false;
|
|
810
|
+
task[TaskIndex.Type] = headerIsString
|
|
811
|
+
? PayloadBuffer.EnvelopeDynamicHeaderStringExternal
|
|
812
|
+
: PayloadBuffer.EnvelopeDynamicHeaderExternal;
|
|
813
|
+
const reservedSlot = reserveDynamicObject(task, headerReserveBytes + bodyLength);
|
|
814
|
+
const baseStart = task[TaskIndex.Start];
|
|
815
|
+
const writtenHeaderBytes = writeDynamicUtf8(headerText, baseStart, headerReserveBytes);
|
|
816
|
+
if (writtenHeaderBytes < 0) {
|
|
817
|
+
return failDynamicWriteAfterReserve(task, reservedSlot);
|
|
818
|
+
}
|
|
819
|
+
const bodyWritten = writeDynamicBinary(bodyBytes, baseStart + writtenHeaderBytes);
|
|
820
|
+
if (bodyWritten < 0) {
|
|
821
|
+
return failDynamicWriteAfterReserve(task, reservedSlot);
|
|
822
|
+
}
|
|
823
|
+
task[TaskIndex.PayloadLen] = writtenHeaderBytes;
|
|
824
|
+
task[TaskIndex.End] = bodyLength;
|
|
825
|
+
setSlotLength(reservedSlot, writtenHeaderBytes + bodyLength);
|
|
826
|
+
attachPayloadTransportFinalizer(task, externalBody);
|
|
827
|
+
task.value = null;
|
|
828
|
+
return true;
|
|
829
|
+
};
|
|
830
|
+
const encodeObjectEnvelope = (task, slotIndex, envelope) => {
|
|
831
|
+
const header = envelope.header;
|
|
832
|
+
const payload = envelope.payload;
|
|
833
|
+
const headerIsString = typeof header === "string";
|
|
834
|
+
if (payload instanceof ArrayBuffer) {
|
|
835
|
+
const headerText = encodeEnvelopeHeaderText(task, header, headerIsString);
|
|
836
|
+
if (headerText === undefined)
|
|
837
|
+
return false;
|
|
838
|
+
return encodeEnvelopeArrayBufferBody(task, slotIndex, headerText, headerIsString, payload);
|
|
839
|
+
}
|
|
840
|
+
const externalBody = resolveEnvelopeExternalBody(payload);
|
|
841
|
+
if (externalBody !== undefined) {
|
|
842
|
+
const headerText = encodeEnvelopeHeaderText(task, header, headerIsString);
|
|
843
|
+
if (headerText === undefined)
|
|
844
|
+
return false;
|
|
845
|
+
return encodeEnvelopeExternalBody(task, slotIndex, headerText, headerIsString, externalBody);
|
|
846
|
+
}
|
|
847
|
+
return encoderError({
|
|
848
|
+
task,
|
|
849
|
+
type: ErrorKnitting.Serializable,
|
|
850
|
+
onPromise,
|
|
851
|
+
detail: ENVELOPE_PAYLOAD_DETAIL,
|
|
852
|
+
});
|
|
853
|
+
};
|
|
721
854
|
const encodeObjectPromise = (task, promise) => {
|
|
722
855
|
if (beginPromisePayload(task)) {
|
|
723
856
|
promise.then((value) => {
|
|
@@ -780,6 +913,10 @@ export const encodePayload = ({ lockSector, payload, sab, payloadConfig, headers
|
|
|
780
913
|
objectDynamicSlot = -1;
|
|
781
914
|
try {
|
|
782
915
|
const objectValue = args;
|
|
916
|
+
const sharedArrayBufferPayload = getSharedArrayBufferPayload(objectValue);
|
|
917
|
+
if (sharedArrayBufferPayload !== undefined) {
|
|
918
|
+
return encodeObjectExternalPayload(task, slotIndex, sharedArrayBufferPayload);
|
|
919
|
+
}
|
|
783
920
|
const objectProto = objectGetPrototypeOf(objectValue);
|
|
784
921
|
if (isRuntimeUint8Array(objectValue)) {
|
|
785
922
|
return encodeObjectUint8Array(task, slotIndex, objectValue);
|
|
@@ -969,7 +1106,13 @@ export const decodePayload = ({ lockSector, payload, sab, payloadConfig, headers
|
|
|
969
1106
|
payloadConfig: resolvedPayloadConfig,
|
|
970
1107
|
textCompat: textCompat?.payload,
|
|
971
1108
|
});
|
|
972
|
-
const { readUtf8: readStaticUtf8,
|
|
1109
|
+
const { readUtf8: readStaticUtf8, readBytesBufferCopy: readStaticBufferCopy, readBufferCopy: readStaticBuffer, readUint8ArrayCopy: readStaticUint8ArrayCopy, readBytesArrayBufferCopy: readStaticArrayBufferCopy, readArrayBufferCopy: readStaticArrayBuffer, read8BytesFloatCopy: readStatic8BytesFloatCopy, readU32Words: readStaticU32Words, } = requireStaticIO(headersBuffer, headerSlotStrideU32, textCompat?.headers);
|
|
1110
|
+
// Reusable scratch for the ProcessSharedBuffer raw-word decode. Safe to share:
|
|
1111
|
+
// decode is single-consumer and not re-entrant, and the words are consumed
|
|
1112
|
+
// synchronously when building the ProcessSharedBuffer.
|
|
1113
|
+
const processSharedBufferWords = new Uint32Array(PROCESS_SHARED_BUFFER_NUMERIC_WORDS);
|
|
1114
|
+
const sharedArrayBufferWords = new Uint32Array(SHARED_ARRAY_BUFFER_NUMERIC_WORDS);
|
|
1115
|
+
const bufferReferenceWords = new Uint32Array(BUFFER_REFERENCE_NUMERIC_WORDS);
|
|
973
1116
|
// TODO: remove slotIndex and make that all their callers
|
|
974
1117
|
// store the slot in their Task, to just get it when it comes
|
|
975
1118
|
// to the static versions of decoding
|
|
@@ -1044,6 +1187,33 @@ export const decodePayload = ({ lockSector, payload, sab, payloadConfig, headers
|
|
|
1044
1187
|
freeTaskSlot(task);
|
|
1045
1188
|
return;
|
|
1046
1189
|
}
|
|
1190
|
+
case PayloadBuffer.EnvelopeStaticHeaderExternal:
|
|
1191
|
+
case PayloadBuffer.EnvelopeStaticHeaderStringExternal: {
|
|
1192
|
+
const rawHeader = readStaticUtf8(0, task[TaskIndex.PayloadLen], slotIndex);
|
|
1193
|
+
const header = task[TaskIndex.Type] ===
|
|
1194
|
+
PayloadBuffer.EnvelopeStaticHeaderStringExternal
|
|
1195
|
+
? rawHeader
|
|
1196
|
+
: parseJSON(rawHeader);
|
|
1197
|
+
const bodyStart = task[TaskIndex.Start];
|
|
1198
|
+
const body = decodeExternalPayload(readDynamicUtf8(bodyStart, bodyStart + task[TaskIndex.End]));
|
|
1199
|
+
task.value = new Envelope(header, body);
|
|
1200
|
+
freeTaskSlot(task);
|
|
1201
|
+
return;
|
|
1202
|
+
}
|
|
1203
|
+
case PayloadBuffer.EnvelopeDynamicHeaderExternal:
|
|
1204
|
+
case PayloadBuffer.EnvelopeDynamicHeaderStringExternal: {
|
|
1205
|
+
const headerStart = task[TaskIndex.Start];
|
|
1206
|
+
const bodyStart = headerStart + task[TaskIndex.PayloadLen];
|
|
1207
|
+
const rawHeader = readDynamicUtf8(headerStart, bodyStart);
|
|
1208
|
+
const header = task[TaskIndex.Type] ===
|
|
1209
|
+
PayloadBuffer.EnvelopeDynamicHeaderStringExternal
|
|
1210
|
+
? rawHeader
|
|
1211
|
+
: parseJSON(rawHeader);
|
|
1212
|
+
const body = decodeExternalPayload(readDynamicUtf8(bodyStart, bodyStart + task[TaskIndex.End]));
|
|
1213
|
+
task.value = new Envelope(header, body);
|
|
1214
|
+
freeTaskSlot(task);
|
|
1215
|
+
return;
|
|
1216
|
+
}
|
|
1047
1217
|
case PayloadBuffer.BigInt:
|
|
1048
1218
|
task.value = decodeBigIntBinary(readDynamicBufferCopy(task[TaskIndex.Start], task[TaskIndex.Start] + task[TaskIndex.PayloadLen]));
|
|
1049
1219
|
freeTaskSlot(task);
|
|
@@ -1118,7 +1288,13 @@ export const decodePayload = ({ lockSector, payload, sab, payloadConfig, headers
|
|
|
1118
1288
|
task.value = decodeExternalPayload(readStaticUtf8(0, task[TaskIndex.PayloadLen], slotIndex));
|
|
1119
1289
|
return;
|
|
1120
1290
|
case PayloadBuffer.ProcessSharedBuffer:
|
|
1121
|
-
task.value =
|
|
1291
|
+
task.value = decodeProcessSharedBufferNumericWords(readStaticU32Words(processSharedBufferWords, PROCESS_SHARED_BUFFER_NUMERIC_WORDS, slotIndex));
|
|
1292
|
+
return;
|
|
1293
|
+
case PayloadBuffer.SharedArrayBuffer:
|
|
1294
|
+
task.value = decodeSharedArrayBufferNumericWords(readStaticU32Words(sharedArrayBufferWords, task[TaskIndex.PayloadLen] >>> 2, slotIndex));
|
|
1295
|
+
return;
|
|
1296
|
+
case PayloadBuffer.BufferReference:
|
|
1297
|
+
task.value = decodeBufferReferenceNumericWords(readStaticU32Words(bufferReferenceWords, BUFFER_REFERENCE_NUMERIC_WORDS, slotIndex));
|
|
1122
1298
|
return;
|
|
1123
1299
|
case PayloadBuffer.Date:
|
|
1124
1300
|
Uint32View[0] = task[TaskIndex.Start];
|
|
@@ -37,6 +37,8 @@ export declare const createSharedStaticBufferIO: ({ headersBuffer, slotStrideU32
|
|
|
37
37
|
writeArrayBuffer: (src: ArrayBuffer, at: number, start?: number) => number;
|
|
38
38
|
writeExactUint8Array: (src: Uint8Array, at: number, start?: number) => number;
|
|
39
39
|
writeUint8Array: (src: Uint8Array, at: number, start?: number) => number;
|
|
40
|
+
writeU32Words: (words: ArrayLike<number>, count: number, at: number) => number;
|
|
41
|
+
readU32Words: (out: Uint32Array, count: number, at: number) => Uint32Array;
|
|
40
42
|
write8Binary: (src: Float64Array, at: number, start?: number) => number;
|
|
41
43
|
readBytesCopy: (start: number, end: number, at: number) => Uint8Array<ArrayBuffer>;
|
|
42
44
|
readBytesView: (start: number, end: number, at: number) => Uint8Array<SharedArrayBuffer>;
|
|
@@ -269,6 +269,27 @@ export const createSharedStaticBufferIO = ({ headersBuffer, slotStrideU32, textC
|
|
|
269
269
|
for (let i = 0; i < LockBound.slots; i++) {
|
|
270
270
|
slotByteOffsets[i] = slotStartBytes(i) - baseByteOffset;
|
|
271
271
|
}
|
|
272
|
+
// The static region is itself a Uint32Array, shared in-process with native
|
|
273
|
+
// endianness. Fixed-shape numeric payloads (e.g. ProcessSharedBuffer
|
|
274
|
+
// descriptors) can be written/read as raw words straight into the slot,
|
|
275
|
+
// skipping the byte scratch + DataView + copy that the generic paths require.
|
|
276
|
+
const baseU32 = new Uint32Array(buffer, baseByteOffset, (buffer.byteLength - baseByteOffset) >>> 2);
|
|
277
|
+
const slotU32Offsets = new Uint32Array(LockBound.slots);
|
|
278
|
+
for (let i = 0; i < LockBound.slots; i++) {
|
|
279
|
+
slotU32Offsets[i] = slotByteOffsets[i] >>> 2;
|
|
280
|
+
}
|
|
281
|
+
const writeU32Words = (words, count, at) => {
|
|
282
|
+
const base = slotU32Offsets[at];
|
|
283
|
+
for (let i = 0; i < count; i++)
|
|
284
|
+
baseU32[base + i] = words[i];
|
|
285
|
+
return count * u32Bytes;
|
|
286
|
+
};
|
|
287
|
+
const readU32Words = (out, count, at) => {
|
|
288
|
+
const base = slotU32Offsets[at];
|
|
289
|
+
for (let i = 0; i < count; i++)
|
|
290
|
+
out[i] = baseU32[base + i];
|
|
291
|
+
return out;
|
|
292
|
+
};
|
|
272
293
|
const canWrite = (start, length) => (start | 0) >= 0 && (start + length) <= writableBytes;
|
|
273
294
|
const writeUtf8 = (str, at) => {
|
|
274
295
|
const start = slotByteOffsets[at];
|
|
@@ -364,6 +385,8 @@ export const createSharedStaticBufferIO = ({ headersBuffer, slotStrideU32, textC
|
|
|
364
385
|
writeArrayBuffer,
|
|
365
386
|
writeExactUint8Array,
|
|
366
387
|
writeUint8Array,
|
|
388
|
+
writeU32Words,
|
|
389
|
+
readU32Words,
|
|
367
390
|
write8Binary,
|
|
368
391
|
readBytesCopy,
|
|
369
392
|
readBytesView,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ComposedWithKey, tasks, WorkerCall } from "../types.js";
|
|
2
2
|
export declare const createInlineExecutor: ({ tasks, genTaskID, batchSize, }: {
|
|
3
|
-
tasks: tasks;
|
|
3
|
+
tasks: tasks | ComposedWithKey[];
|
|
4
4
|
genTaskID: () => number;
|
|
5
5
|
batchSize?: number;
|
|
6
6
|
}) => {
|
|
@@ -69,9 +69,21 @@ const composeInlineCallable = (fn, timeout, useAbortToolkit = false) => {
|
|
|
69
69
|
};
|
|
70
70
|
};
|
|
71
71
|
export const createInlineExecutor = ({ tasks, genTaskID, batchSize, }) => {
|
|
72
|
-
const entries =
|
|
73
|
-
|
|
74
|
-
|
|
72
|
+
const entries = Array.isArray(tasks)
|
|
73
|
+
? tasks
|
|
74
|
+
: Object.values(tasks).sort((a, b) => a.id - b.id);
|
|
75
|
+
const runners = entries.map((entry) => {
|
|
76
|
+
// Imported tasks must never execute on the host inline lane: their module
|
|
77
|
+
// import is meant to stay inside the worker so worker permission policies
|
|
78
|
+
// apply. The pool already routes them to worker lanes, but guard here as
|
|
79
|
+
// defense in depth so a dispatch regression can't silently import on host.
|
|
80
|
+
if (entry.imported === true) {
|
|
81
|
+
return () => {
|
|
82
|
+
throw new Error("Imported task cannot run on the host inline lane");
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
return composeInlineCallable(entry.f, entry.timeout, entry.abortSignal !== undefined);
|
|
86
|
+
});
|
|
75
87
|
const initCap = 16;
|
|
76
88
|
let fnByIndex = new Int32Array(initCap);
|
|
77
89
|
let stateByIndex = new Int8Array(initCap).fill(-1 /* SlotStateMacro.Free */);
|
package/src/runtime/pool.d.ts
CHANGED
|
@@ -4,9 +4,10 @@ import { lock2 } from "../memory/lock.js";
|
|
|
4
4
|
import type { DebugOptions, DispatcherSettings, WorkerContext, WorkerData, WorkerSettings } from "../types.js";
|
|
5
5
|
import "../worker/loop.js";
|
|
6
6
|
import { type PayloadBufferOptions } from "../memory/payload-config.js";
|
|
7
|
-
export declare const spawnWorkerContext: ({ list, ids, sab, thread, debug, totalNumberOfThread, source, at, workerOptions, workerExecArgv, permission, host, payload, payloadInitialBytes, payloadMaxBytes, bufferMode, maxPayloadBytes, abortSignalCapacity, usesAbortSignal, }: {
|
|
7
|
+
export declare const spawnWorkerContext: ({ list, ids, names, sab, thread, debug, totalNumberOfThread, source, at, workerOptions, workerExecArgv, permission, host, payload, bufferReferenceReturn, payloadInitialBytes, payloadMaxBytes, bufferMode, maxPayloadBytes, abortSignalCapacity, usesAbortSignal, }: {
|
|
8
8
|
list: string[];
|
|
9
9
|
ids: number[];
|
|
10
|
+
names: string[];
|
|
10
11
|
at: number[];
|
|
11
12
|
sab?: Sab;
|
|
12
13
|
thread: number;
|
|
@@ -18,6 +19,7 @@ export declare const spawnWorkerContext: ({ list, ids, sab, thread, debug, total
|
|
|
18
19
|
permission?: WorkerData["permission"];
|
|
19
20
|
host?: DispatcherSettings;
|
|
20
21
|
payload?: PayloadBufferOptions;
|
|
22
|
+
bufferReferenceReturn?: "copy" | "borrow";
|
|
21
23
|
payloadInitialBytes?: number;
|
|
22
24
|
payloadMaxBytes?: number;
|
|
23
25
|
bufferMode?: PayloadBufferOptions["mode"];
|
package/src/runtime/pool.js
CHANGED
|
@@ -10,6 +10,7 @@ import { probeLockBufferTextCompat } from "../common/shared-buffer-text.js";
|
|
|
10
10
|
import { signalAbortFactory } from "../shared/abortSignal.js";
|
|
11
11
|
import { createLockControlCarpet } from "../memory/byte-carpet.js";
|
|
12
12
|
import { resolvePayloadBufferOptions, } from "../memory/payload-config.js";
|
|
13
|
+
import { createBufferReferenceReturnReleaseMessage } from "../connections/buffer-reference.js";
|
|
13
14
|
const WORKER_FATAL_MESSAGE_KEY = "__knittingWorkerFatal";
|
|
14
15
|
const isWorkerFatalMessage = (value) => !!value &&
|
|
15
16
|
typeof value === "object" &&
|
|
@@ -33,7 +34,7 @@ const withFixedPayloadConfig = (config) => ({
|
|
|
33
34
|
mode: "fixed",
|
|
34
35
|
payloadInitialBytes: config.payloadMaxByteLength,
|
|
35
36
|
});
|
|
36
|
-
export const spawnWorkerContext = ({ list, ids, sab, thread, debug, totalNumberOfThread, source, at, workerOptions, workerExecArgv, permission, host, payload, payloadInitialBytes, payloadMaxBytes, bufferMode, maxPayloadBytes, abortSignalCapacity, usesAbortSignal, }) => {
|
|
37
|
+
export const spawnWorkerContext = ({ list, ids, names, sab, thread, debug, totalNumberOfThread, source, at, workerOptions, workerExecArgv, permission, host, payload, bufferReferenceReturn, payloadInitialBytes, payloadMaxBytes, bufferMode, maxPayloadBytes, abortSignalCapacity, usesAbortSignal, }) => {
|
|
37
38
|
const tsFileUrl = new URL(import.meta.url);
|
|
38
39
|
const poliWorker = RUNTIME_WORKER;
|
|
39
40
|
const resolvedWorkerOptions = serializeWorkerBootstrapData(withDefaultWorkerTimers(workerOptions));
|
|
@@ -193,6 +194,11 @@ export const spawnWorkerContext = ({ list, ids, sab, thread, debug, totalNumberO
|
|
|
193
194
|
lock,
|
|
194
195
|
returnLock,
|
|
195
196
|
abortSignals,
|
|
197
|
+
releaseBufferReferenceReturn: bufferReferenceReturn === "borrow"
|
|
198
|
+
? (token) => {
|
|
199
|
+
worker?.postMessage?.(createBufferReferenceReturnReleaseMessage(token));
|
|
200
|
+
}
|
|
201
|
+
: undefined,
|
|
196
202
|
});
|
|
197
203
|
const { enqueue, rejectAll, txIdle, } = queue;
|
|
198
204
|
const channelHandler = new ChannelHandler();
|
|
@@ -217,6 +223,7 @@ export const spawnWorkerContext = ({ list, ids, sab, thread, debug, totalNumberO
|
|
|
217
223
|
: undefined,
|
|
218
224
|
list,
|
|
219
225
|
ids,
|
|
226
|
+
names,
|
|
220
227
|
at,
|
|
221
228
|
thread,
|
|
222
229
|
debug,
|
|
@@ -226,6 +233,7 @@ export const spawnWorkerContext = ({ list, ids, sab, thread, debug, totalNumberO
|
|
|
226
233
|
lock: lockBuffers,
|
|
227
234
|
returnLock: returnLockBuffers,
|
|
228
235
|
payloadConfig: resolvedPayloadConfig,
|
|
236
|
+
bufferReferenceReturn,
|
|
229
237
|
permission,
|
|
230
238
|
};
|
|
231
239
|
const baseWorkerOptions = {
|
|
@@ -2,7 +2,7 @@ import { fileURLToPath as fileURLToPathCompat } from "node:url";
|
|
|
2
2
|
import { HEADER_SLOT_STRIDE_U32, LOCK_SECTOR_BYTE_LENGTH, LockBound, } from "../memory/lock.js";
|
|
3
3
|
import { createByteCarpet, getHeaderBlockByteLength, makeSharedBufferRegion, } from "../memory/byte-carpet.js";
|
|
4
4
|
import { RUNTIME } from "../common/runtime.js";
|
|
5
|
-
import { RUNTIME_PROCESS_WORKER_BOOT_ENV, RUNTIME_PROCESS_WORKER_BOOT_VERSION, RUNTIME_PROCESS_WORKER_ENV, } from "../common/worker-runtime.js";
|
|
5
|
+
import { RUNTIME_POOL_DEPTH, RUNTIME_POOL_DEPTH_ENV, RUNTIME_PROCESS_WORKER_BOOT_ENV, RUNTIME_PROCESS_WORKER_BOOT_VERSION, RUNTIME_PROCESS_WORKER_ENV, } from "../common/worker-runtime.js";
|
|
6
6
|
import { getNodeBuiltinModule, getNodeProcess } from "../common/node-compat.js";
|
|
7
7
|
import { toSharedBufferRegion, } from "../common/shared-buffer-region.js";
|
|
8
8
|
import { createBunConnectionPrimitives } from "../connections/bun.js";
|
|
@@ -100,6 +100,7 @@ const DEFAULT_NODE_BINARY = "node";
|
|
|
100
100
|
const DENO_PROCESS_WORKER_BOOT_ENV_ALLOW = [
|
|
101
101
|
RUNTIME_PROCESS_WORKER_ENV,
|
|
102
102
|
RUNTIME_PROCESS_WORKER_BOOT_ENV,
|
|
103
|
+
RUNTIME_POOL_DEPTH_ENV,
|
|
103
104
|
].join(",");
|
|
104
105
|
const DENO_PROCESS_WORKER_INTERNAL_FLAGS = [
|
|
105
106
|
`--allow-env=${DENO_PROCESS_WORKER_BOOT_ENV_ALLOW}`,
|
|
@@ -354,6 +355,7 @@ const currentProcessEnv = () => ({
|
|
|
354
355
|
const processWorkerEnv = (extra) => ({
|
|
355
356
|
...currentProcessEnv(),
|
|
356
357
|
[RUNTIME_PROCESS_WORKER_ENV]: "1",
|
|
358
|
+
[RUNTIME_POOL_DEPTH_ENV]: String(RUNTIME_POOL_DEPTH + 1),
|
|
357
359
|
...extra,
|
|
358
360
|
});
|
|
359
361
|
const processWorkerBootEnv = (bootPayload) => processWorkerEnv({
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type Lock2, type Task } from "../memory/lock.js";
|
|
2
2
|
import type { AbortSignalOption, TaskTimeout } from "../types.js";
|
|
3
3
|
import { type SignalAbortStore } from "../shared/abortSignal.js";
|
|
4
4
|
type RawArguments = unknown;
|
|
@@ -9,10 +9,11 @@ type CreateHostTxQueueArgs = {
|
|
|
9
9
|
max?: number;
|
|
10
10
|
lock: Lock2;
|
|
11
11
|
returnLock: Lock2;
|
|
12
|
+
releaseBufferReferenceReturn?: (token: bigint) => void;
|
|
12
13
|
abortSignals?: Pick<SignalAbortStore, "getSignal" | "setSignal" | "resetSignal" | "closeNow">;
|
|
13
14
|
now?: () => number;
|
|
14
15
|
};
|
|
15
|
-
export declare function createHostTxQueue({ max, lock, returnLock, abortSignals, now, }: CreateHostTxQueueArgs): {
|
|
16
|
+
export declare function createHostTxQueue({ max, lock, returnLock, releaseBufferReferenceReturn, abortSignals, now, }: CreateHostTxQueueArgs): {
|
|
16
17
|
rejectAll: (reason: string) => void;
|
|
17
18
|
hasPendingFrames: () => boolean;
|
|
18
19
|
txIdle: () => boolean;
|