@masons/runtime-broker 0.2.8 → 0.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/broker/broker-daemon.d.ts +1 -0
- package/dist/broker/broker-daemon.d.ts.map +1 -1
- package/dist/broker/broker-daemon.js +124 -13
- package/dist/broker/entry.d.ts +1 -0
- package/dist/broker/entry.d.ts.map +1 -1
- package/dist/broker/entry.js +42 -1
- package/dist/broker/ipc-server.d.ts +6 -1
- package/dist/broker/ipc-server.d.ts.map +1 -1
- package/dist/broker/ipc-server.js +26 -2
- package/dist/broker/version-handshake.d.ts +2 -1
- package/dist/broker/version-handshake.d.ts.map +1 -1
- package/dist/broker/version-handshake.js +2 -1
- package/dist/broker-client/broker-client.d.ts +13 -0
- package/dist/broker-client/broker-client.d.ts.map +1 -1
- package/dist/broker-client/broker-client.js +92 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
|
@@ -58,6 +58,7 @@ export interface BrokerDaemonOptions {
|
|
|
58
58
|
runtimeInboundRoutedBackoffMaxMs?: number;
|
|
59
59
|
runtimeInboundRoutedMaxRetries?: number;
|
|
60
60
|
runtimeAssignmentAcceptanceTimeoutMs?: number;
|
|
61
|
+
pushReceiptAckTimeoutMs?: number;
|
|
61
62
|
}
|
|
62
63
|
export interface RunningBroker {
|
|
63
64
|
bearerToken: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"broker-daemon.d.ts","sourceRoot":"","sources":["../../src/broker/broker-daemon.ts"],"names":[],"mappings":"AA2BA,OAAO,EAAqB,KAAK,IAAI,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAE5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAQjD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EACL,KAAK,sBAAsB,EAE5B,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EACV,UAAU,EAIX,MAAM,0BAA0B,CAAC;AAKlC,OAAO,EACL,KAAK,eAAe,EAKrB,MAAM,qBAAqB,CAAC;AAK7B,OAAO,EAEL,KAAK,aAAa,EAEnB,MAAM,6BAA6B,CAAC;AAiBrC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EACL,KAAK,eAAe,EAErB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,2CAA2C,CAAC;AAM7F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAO9C,OAAO,EACL,KAAK,eAAe,EAErB,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAEV,mBAAmB,EACpB,MAAM,4BAA4B,CAAC;AAMpC,OAAO,KAAK,EACV,6BAA6B,EAC7B,yBAAyB,EAC1B,MAAM,yCAAyC,CAAC;AAKjD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAKtE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAG7D,OAAO,EAGL,KAAK,wBAAwB,EAC9B,MAAM,uCAAuC,CAAC;AAM/C,OAAO,EAEL,KAAK,iBAAiB,EAEvB,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"broker-daemon.d.ts","sourceRoot":"","sources":["../../src/broker/broker-daemon.ts"],"names":[],"mappings":"AA2BA,OAAO,EAAqB,KAAK,IAAI,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAE5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAQjD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EACL,KAAK,sBAAsB,EAE5B,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EACV,UAAU,EAIX,MAAM,0BAA0B,CAAC;AAKlC,OAAO,EACL,KAAK,eAAe,EAKrB,MAAM,qBAAqB,CAAC;AAK7B,OAAO,EAEL,KAAK,aAAa,EAEnB,MAAM,6BAA6B,CAAC;AAiBrC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EACL,KAAK,eAAe,EAErB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,2CAA2C,CAAC;AAM7F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAO9C,OAAO,EACL,KAAK,eAAe,EAErB,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAEV,mBAAmB,EACpB,MAAM,4BAA4B,CAAC;AAMpC,OAAO,KAAK,EACV,6BAA6B,EAC7B,yBAAyB,EAC1B,MAAM,yCAAyC,CAAC;AAKjD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAKtE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAG7D,OAAO,EAGL,KAAK,wBAAwB,EAC9B,MAAM,uCAAuC,CAAC;AAM/C,OAAO,EAEL,KAAK,iBAAiB,EAEvB,MAAM,yBAAyB,CAAC;AAuDjC,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,WAAW,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,WAAW,CAAC;IACvB,OAAO,EAAE,mBAAmB,CAAC;IAC7B,MAAM,EAAE,YAAY,CAAC;IAGrB,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAE5C,aAAa,CAAC,EAAE,MAAM,CAAC;IAGvB,OAAO,CAAC,EAAE,MAAM,CAAC;IAGjB,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC;IAKhD,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAG1C,OAAO,CAAC,EAAE,OAAO,UAAU,CAAC;IAG5B,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAGhC,yBAAyB,CAAC,EAAE,MAAM,CAAC;IAGnC,eAAe,CAAC,EAAE,MAAM,CAAC;IAGzB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAK5B,0BAA0B,CAAC,EAAE,CAAC,IAAI,EAAE;QAClC,UAAU,EAAE,sBAAsB,CAAC;QACnC,MAAM,EAAE,YAAY,CAAC;KACtB,KAAK,mBAAmB,CAAC;IAK1B,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAQpD,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAI/B,8BAA8B,CAAC,EAAE,MAAM,CAAC;IAIxC,uBAAuB,CAAC,EAAE,CACxB,KAAK,EAAE,wBAAwB,KAC5B,OAAO,CAAC,OAAO,4BAA4B,EAAE,WAAW,CAAC,CAAC;IAG/D,2BAA2B,CAAC,EAAE,MAAM,CAAC;IAErC,mCAAmC,CAAC,EAAE,MAAM,CAAC;IAE7C,+BAA+B,CAAC,EAAE,MAAM,CAAC;IAEzC,6BAA6B,CAAC,EAAE,MAAM,CAAC;IAIvC,0BAA0B,CAAC,EAAE,CAC3B,KAAK,EAAE,2BAA2B,KAC/B,OAAO,CAAC,OAAO,4BAA4B,EAAE,WAAW,CAAC,CAAC;IAI/D,8BAA8B,CAAC,EAAE,MAAM,CAAC;IAExC,sCAAsC,CAAC,EAAE,MAAM,CAAC;IAEhD,kCAAkC,CAAC,EAAE,MAAM,CAAC;IAE5C,gCAAgC,CAAC,EAAE,MAAM,CAAC;IAG1C,wBAAwB,CAAC,EAAE,CACzB,KAAK,EAAE,yBAAyB,KAC7B,OAAO,CAAC,OAAO,4BAA4B,EAAE,WAAW,CAAC,CAAC;IAG/D,4BAA4B,CAAC,EAAE,CAC7B,KAAK,EAAE,6BAA6B,KACjC,OAAO,CACV,OAAO,+BAA+B,EAAE,+BAA+B,CACxE,CAAC;IAEF,4BAA4B,CAAC,EAAE,MAAM,CAAC;IAEtC,oCAAoC,CAAC,EAAE,MAAM,CAAC;IAE9C,gCAAgC,CAAC,EAAE,MAAM,CAAC;IAE1C,8BAA8B,CAAC,EAAE,MAAM,CAAC;IAExC,oCAAoC,CAAC,EAAE,MAAM,CAAC;IAE9C,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC;AAgBD,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAExC,YAAY,IAAI,MAAM,CAAC;IAGvB,KAAK,CAAC,WAAW,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAAC;IAEtD,iBAAiB,EAAE,iBAAiB,CAAC;IAErC,sBAAsB,EAAE,sBAAsB,CAAC;IAE/C,eAAe,IAAI,eAAe,CAAC;IAEnC,iBAAiB,IAAI,MAAM,CAAC;IAE5B,cAAc,IAAI,MAAM,CAAC;IAGzB,yBAAyB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IAGvD,4BAA4B,IAAI,MAAM,CAAC;IAGvC,+BAA+B,IAAI,MAAM,CAAC;IAE1C,6BAA6B,IAAI,MAAM,CAAC;CACzC;AAED,qBAAa,yBAA0B,SAAQ,KAAK;IAClD,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;gBAExB,SAAS,EAAE,eAAe;CAOvC;AA4BD,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,mBAAmB,GACxB,OAAO,CAAC,aAAa,CAAC,CAiuFxB;AAGD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,GAAG,IAAI,CAMvE;AAED,YAAY,EAAE,eAAe,EAAE,CAAC"}
|
|
@@ -24,6 +24,7 @@ import { createUndispatchedChangedEmitter, postUndispatchedChangedViaPort, } fro
|
|
|
24
24
|
import { createUndispatchedInbox, } from "./undispatched-inbox.js";
|
|
25
25
|
const REMOTE_SPAWN_CAPABILITY = "remote_spawn_v1";
|
|
26
26
|
const DEFAULT_RUNTIME_ASSIGNMENT_ACCEPTANCE_TIMEOUT_MS = 30_000;
|
|
27
|
+
const DEFAULT_PUSH_RECEIPT_ACK_TIMEOUT_MS = 2_000;
|
|
27
28
|
const RUNTIME_ASSIGNMENT_REPLY_RECORD_TTL_MS = 24 * 60 * 60 * 1000;
|
|
28
29
|
const RUNTIME_PROCESSING_RETRY_INITIAL_MS = 1_000;
|
|
29
30
|
const RUNTIME_PROCESSING_RETRY_MAX_MS = 30_000;
|
|
@@ -100,6 +101,7 @@ export async function startBrokerDaemon(opts) {
|
|
|
100
101
|
const presenceGraceMs = opts.presenceGraceMs;
|
|
101
102
|
const runtimeAssignmentAcceptanceTimeoutMs = opts.runtimeAssignmentAcceptanceTimeoutMs ??
|
|
102
103
|
DEFAULT_RUNTIME_ASSIGNMENT_ACCEPTANCE_TIMEOUT_MS;
|
|
104
|
+
const pushReceiptAckTimeoutMs = opts.pushReceiptAckTimeoutMs ?? DEFAULT_PUSH_RECEIPT_ACK_TIMEOUT_MS;
|
|
103
105
|
const postControlAck = opts.postControlAck ??
|
|
104
106
|
(async () => {
|
|
105
107
|
});
|
|
@@ -539,6 +541,65 @@ export async function startBrokerDaemon(opts) {
|
|
|
539
541
|
}
|
|
540
542
|
};
|
|
541
543
|
const channels = new Map();
|
|
544
|
+
const channelCapabilities = new WeakMap();
|
|
545
|
+
const pendingPushAcks = new Map();
|
|
546
|
+
const settlePushAck = (pushId, ok) => {
|
|
547
|
+
const pending = pendingPushAcks.get(pushId);
|
|
548
|
+
if (!pending)
|
|
549
|
+
return;
|
|
550
|
+
pendingPushAcks.delete(pushId);
|
|
551
|
+
clearTimeout(pending.timer);
|
|
552
|
+
pending.resolve(ok);
|
|
553
|
+
};
|
|
554
|
+
const waitForPushAck = (plugin_pid, ipc_ws, pushId, event, endpoint_id) => new Promise((resolve) => {
|
|
555
|
+
const timer = setTimeout(() => {
|
|
556
|
+
logger.warn("ipc_push_ack_timeout", {
|
|
557
|
+
push_id: pushId,
|
|
558
|
+
plugin_pid,
|
|
559
|
+
event,
|
|
560
|
+
endpoint_id,
|
|
561
|
+
});
|
|
562
|
+
settlePushAck(pushId, false);
|
|
563
|
+
}, pushReceiptAckTimeoutMs);
|
|
564
|
+
timer.unref?.();
|
|
565
|
+
pendingPushAcks.set(pushId, {
|
|
566
|
+
plugin_pid,
|
|
567
|
+
ipc_ws,
|
|
568
|
+
endpoint_id,
|
|
569
|
+
event,
|
|
570
|
+
timer,
|
|
571
|
+
resolve,
|
|
572
|
+
});
|
|
573
|
+
});
|
|
574
|
+
const pushToPluginWithReceipt = async (entry, event) => {
|
|
575
|
+
const capabilities = channelCapabilities.get(entry.ipc_ws);
|
|
576
|
+
if (capabilities?.push_receipt_ack_v1 !== true) {
|
|
577
|
+
return pushToPlugin(entry.ipc_ws, event);
|
|
578
|
+
}
|
|
579
|
+
const pushId = `push_${randomUUID()}`;
|
|
580
|
+
const ack = waitForPushAck(entry.plugin_pid, entry.ipc_ws, pushId, event.event, entry.endpoint_id);
|
|
581
|
+
let pushed = false;
|
|
582
|
+
try {
|
|
583
|
+
pushed = pushToPlugin(entry.ipc_ws, {
|
|
584
|
+
...event,
|
|
585
|
+
push_id: pushId,
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
catch (err) {
|
|
589
|
+
logger.warn("ipc_push_send_failed", {
|
|
590
|
+
push_id: pushId,
|
|
591
|
+
endpoint_id: entry.endpoint_id,
|
|
592
|
+
plugin_pid: entry.plugin_pid,
|
|
593
|
+
event: event.event,
|
|
594
|
+
err: err instanceof Error ? err.message : String(err),
|
|
595
|
+
});
|
|
596
|
+
}
|
|
597
|
+
if (!pushed) {
|
|
598
|
+
settlePushAck(pushId, false);
|
|
599
|
+
return false;
|
|
600
|
+
}
|
|
601
|
+
return ack;
|
|
602
|
+
};
|
|
542
603
|
let networkPresence = "offline";
|
|
543
604
|
let presenceGraceTimer;
|
|
544
605
|
const applyPresenceTransition = (event) => {
|
|
@@ -918,7 +979,6 @@ export async function startBrokerDaemon(opts) {
|
|
|
918
979
|
storedAssignment.lastStateSequence = Math.max(storedAssignment.lastStateSequence, processingEvent.state_sequence);
|
|
919
980
|
runtimeAssignments.set(assignmentKey, storedAssignment);
|
|
920
981
|
scheduleAcceptanceTimeout(assignmentKey);
|
|
921
|
-
rememberRuntimeAssignmentCorrelation(target.endpoint_id, taken.metadata.correlation_id, assignmentKey);
|
|
922
982
|
const stamped = {
|
|
923
983
|
event: "message_received",
|
|
924
984
|
from: taken.sender_address,
|
|
@@ -932,15 +992,26 @@ export async function startBrokerDaemon(opts) {
|
|
|
932
992
|
sourceMessageId: taken.source_message_id,
|
|
933
993
|
runtimeAssignment,
|
|
934
994
|
};
|
|
935
|
-
recordInboundCorrelation(target.endpoint_id, stamped.metadata);
|
|
936
995
|
if (target.state === "active") {
|
|
937
|
-
if (!
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
996
|
+
if (!(await pushToPluginWithReceipt(target, stamped))) {
|
|
997
|
+
const current = runtimeAssignments.get(assignmentKey);
|
|
998
|
+
if (current?.accepted) {
|
|
999
|
+
logger.info("ipc_push_ack_missing_after_adapter_accept", {
|
|
1000
|
+
assignment_id: runtimeAssignment.assignmentId,
|
|
1001
|
+
source_message_id: runtimeAssignment.sourceMessageId,
|
|
1002
|
+
target_endpoint_id: target.endpoint_id,
|
|
1003
|
+
});
|
|
1004
|
+
}
|
|
1005
|
+
else {
|
|
1006
|
+
await restorePendingAssignmentsForEndpoint(target.endpoint_id, "ipc_push_not_received");
|
|
1007
|
+
return {
|
|
1008
|
+
ok: false,
|
|
1009
|
+
detail: `target endpoint did not acknowledge push receipt: ${targetEndpointId}`,
|
|
1010
|
+
};
|
|
1011
|
+
}
|
|
943
1012
|
}
|
|
1013
|
+
rememberRuntimeAssignmentCorrelation(target.endpoint_id, taken.metadata.correlation_id, assignmentKey);
|
|
1014
|
+
recordInboundCorrelation(target.endpoint_id, stamped.metadata);
|
|
944
1015
|
}
|
|
945
1016
|
else {
|
|
946
1017
|
try {
|
|
@@ -1483,10 +1554,10 @@ export async function startBrokerDaemon(opts) {
|
|
|
1483
1554
|
const buf = reconnectingBuffers.forEndpoint(endpoint_id);
|
|
1484
1555
|
const drained = buf.read();
|
|
1485
1556
|
graceTimers.cancel(endpoint_id);
|
|
1486
|
-
registry.markActive(endpoint_id, ipcWs);
|
|
1557
|
+
const activeEntry = registry.markActive(endpoint_id, ipcWs);
|
|
1487
1558
|
let allPushed = true;
|
|
1488
1559
|
for (const msg of drained) {
|
|
1489
|
-
const pushed =
|
|
1560
|
+
const pushed = await pushToPluginWithReceipt(activeEntry, {
|
|
1490
1561
|
event: "message_received",
|
|
1491
1562
|
from: msg.envelope.from,
|
|
1492
1563
|
content: msg.envelope.content,
|
|
@@ -1582,7 +1653,7 @@ export async function startBrokerDaemon(opts) {
|
|
|
1582
1653
|
handlers,
|
|
1583
1654
|
logger,
|
|
1584
1655
|
getNetworkPresence: () => networkPresence,
|
|
1585
|
-
onChannelOpened: (plugin_pid, ws) => {
|
|
1656
|
+
onChannelOpened: (plugin_pid, ws, clientCapabilities) => {
|
|
1586
1657
|
const prior = channels.get(plugin_pid);
|
|
1587
1658
|
if (prior && prior !== ws) {
|
|
1588
1659
|
displacedWs.add(prior);
|
|
@@ -1593,11 +1664,50 @@ export async function startBrokerDaemon(opts) {
|
|
|
1593
1664
|
}
|
|
1594
1665
|
}
|
|
1595
1666
|
channels.set(plugin_pid, ws);
|
|
1667
|
+
channelCapabilities.set(ws, clientCapabilities);
|
|
1668
|
+
},
|
|
1669
|
+
onPushAck: (plugin_pid, ws, push_id) => {
|
|
1670
|
+
const pending = pendingPushAcks.get(push_id);
|
|
1671
|
+
if (!pending) {
|
|
1672
|
+
logger.debug("ipc_push_ack_unknown", { plugin_pid, push_id });
|
|
1673
|
+
return;
|
|
1674
|
+
}
|
|
1675
|
+
if (pending.plugin_pid !== plugin_pid) {
|
|
1676
|
+
logger.warn("ipc_push_ack_pid_mismatch", {
|
|
1677
|
+
push_id,
|
|
1678
|
+
expected_plugin_pid: pending.plugin_pid,
|
|
1679
|
+
actual_plugin_pid: plugin_pid,
|
|
1680
|
+
event: pending.event,
|
|
1681
|
+
endpoint_id: pending.endpoint_id,
|
|
1682
|
+
});
|
|
1683
|
+
return;
|
|
1684
|
+
}
|
|
1685
|
+
if (pending.ipc_ws !== ws) {
|
|
1686
|
+
logger.warn("ipc_push_ack_ws_mismatch", {
|
|
1687
|
+
push_id,
|
|
1688
|
+
plugin_pid,
|
|
1689
|
+
event: pending.event,
|
|
1690
|
+
endpoint_id: pending.endpoint_id,
|
|
1691
|
+
});
|
|
1692
|
+
return;
|
|
1693
|
+
}
|
|
1694
|
+
settlePushAck(push_id, true);
|
|
1596
1695
|
},
|
|
1597
1696
|
onChannelClosed: (plugin_pid, ws) => {
|
|
1598
1697
|
if (channels.get(plugin_pid) === ws) {
|
|
1599
1698
|
channels.delete(plugin_pid);
|
|
1600
1699
|
}
|
|
1700
|
+
for (const [pushId, pending] of Array.from(pendingPushAcks.entries())) {
|
|
1701
|
+
if (pending.plugin_pid === plugin_pid && pending.ipc_ws === ws) {
|
|
1702
|
+
logger.warn("ipc_push_ack_channel_closed", {
|
|
1703
|
+
push_id: pushId,
|
|
1704
|
+
plugin_pid,
|
|
1705
|
+
event: pending.event,
|
|
1706
|
+
endpoint_id: pending.endpoint_id,
|
|
1707
|
+
});
|
|
1708
|
+
settlePushAck(pushId, false);
|
|
1709
|
+
}
|
|
1710
|
+
}
|
|
1601
1711
|
if (displacedWs.has(ws))
|
|
1602
1712
|
return;
|
|
1603
1713
|
const bound = wsEndpoints.get(ws);
|
|
@@ -1786,9 +1896,8 @@ export async function startBrokerDaemon(opts) {
|
|
|
1786
1896
|
routed_at: Date.now(),
|
|
1787
1897
|
};
|
|
1788
1898
|
}
|
|
1789
|
-
recordInboundCorrelation(decision.entry.endpoint_id, meta);
|
|
1790
1899
|
if (decision.entry.state === "active") {
|
|
1791
|
-
const pushed =
|
|
1900
|
+
const pushed = await pushToPluginWithReceipt(decision.entry, {
|
|
1792
1901
|
event: "message_received",
|
|
1793
1902
|
from: payload.from,
|
|
1794
1903
|
content: payload.content,
|
|
@@ -1800,6 +1909,7 @@ export async function startBrokerDaemon(opts) {
|
|
|
1800
1909
|
});
|
|
1801
1910
|
if (!pushed)
|
|
1802
1911
|
return false;
|
|
1912
|
+
recordInboundCorrelation(decision.entry.endpoint_id, meta);
|
|
1803
1913
|
}
|
|
1804
1914
|
else {
|
|
1805
1915
|
const buf = reconnectingBuffers.forEndpoint(decision.entry.endpoint_id);
|
|
@@ -1825,6 +1935,7 @@ export async function startBrokerDaemon(opts) {
|
|
|
1825
1935
|
});
|
|
1826
1936
|
return false;
|
|
1827
1937
|
}
|
|
1938
|
+
recordInboundCorrelation(decision.entry.endpoint_id, meta);
|
|
1828
1939
|
logger.info("buffered_for_reconnecting_endpoint", {
|
|
1829
1940
|
endpoint_id: decision.entry.endpoint_id,
|
|
1830
1941
|
buffer_size: buf.size(),
|
package/dist/broker/entry.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ interface RuntimePrincipal {
|
|
|
15
15
|
export declare function resolveCredentialsFromFile(filePath: string, accountId: string, envApiHost: string | undefined): Promise<ResolvedCredentials>;
|
|
16
16
|
export declare function resolveRuntimePrincipal(apiHost: string, runtimeKey: string, fetchImpl?: typeof globalThis.fetch): Promise<RuntimePrincipal>;
|
|
17
17
|
export declare function buildApiPort(apiHost: string, runtimeKey: string, logger: BrokerLogger): RuntimeEndpointPort;
|
|
18
|
+
export declare function installFatalExitHandlers(logger: BrokerLogger): void;
|
|
18
19
|
export declare function main(): Promise<void>;
|
|
19
20
|
export {};
|
|
20
21
|
//# sourceMappingURL=entry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entry.d.ts","sourceRoot":"","sources":["../../src/broker/entry.ts"],"names":[],"mappings":"AAsFA,OAAO,EAAE,KAAK,YAAY,EAAsB,MAAM,aAAa,CAAC;AAEpE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"entry.d.ts","sourceRoot":"","sources":["../../src/broker/entry.ts"],"names":[],"mappings":"AAsFA,OAAO,EAAE,KAAK,YAAY,EAAsB,MAAM,aAAa,CAAC;AAEpE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAOtE,UAAU,mBAAmB;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,gBAAgB;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAUD,wBAAsB,0BAA0B,CAC9C,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,OAAO,CAAC,mBAAmB,CAAC,CA8F9B;AA2DD,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,GAAE,OAAO,UAAU,CAAC,KAAwB,GACpD,OAAO,CAAC,gBAAgB,CAAC,CA4B3B;AAaD,wBAAgB,YAAY,CAC1B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,YAAY,GACnB,mBAAmB,CAqIrB;AAyCD,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAenE;AAED,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAiG1C"}
|
package/dist/broker/entry.js
CHANGED
|
@@ -12,6 +12,7 @@ import { resolveBrokerPaths } from "./paths.js";
|
|
|
12
12
|
import { createServicesEventClient } from "./services-event-client.js";
|
|
13
13
|
import { SpawnDriverRegistry } from "./spawn-driver.js";
|
|
14
14
|
const DEFAULT_ACCOUNT_ID = "default";
|
|
15
|
+
let entryLogger = null;
|
|
15
16
|
export async function resolveCredentialsFromFile(filePath, accountId, envApiHost) {
|
|
16
17
|
let raw;
|
|
17
18
|
try {
|
|
@@ -191,6 +192,40 @@ function errorStatus(err) {
|
|
|
191
192
|
function sleep(ms) {
|
|
192
193
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
193
194
|
}
|
|
195
|
+
function serializeFatalReason(reason) {
|
|
196
|
+
if (reason instanceof Error) {
|
|
197
|
+
return {
|
|
198
|
+
name: reason.name,
|
|
199
|
+
message: reason.message,
|
|
200
|
+
stack: reason.stack,
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
return { message: String(reason) };
|
|
204
|
+
}
|
|
205
|
+
function logBrokerFatalExit(kind, reason) {
|
|
206
|
+
const fields = {
|
|
207
|
+
kind,
|
|
208
|
+
...serializeFatalReason(reason),
|
|
209
|
+
};
|
|
210
|
+
if (entryLogger) {
|
|
211
|
+
entryLogger.error("broker_fatal_exit", fields);
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
console.error("broker_fatal_exit", fields);
|
|
215
|
+
}
|
|
216
|
+
export function installFatalExitHandlers(logger) {
|
|
217
|
+
entryLogger = logger;
|
|
218
|
+
let fatalExitStarted = false;
|
|
219
|
+
const exitAfterLog = (kind, reason) => {
|
|
220
|
+
if (fatalExitStarted)
|
|
221
|
+
return;
|
|
222
|
+
fatalExitStarted = true;
|
|
223
|
+
logBrokerFatalExit(kind, reason);
|
|
224
|
+
process.exit(1);
|
|
225
|
+
};
|
|
226
|
+
process.on("uncaughtException", (err) => exitAfterLog("uncaughtException", err));
|
|
227
|
+
process.on("unhandledRejection", (reason) => exitAfterLog("unhandledRejection", reason));
|
|
228
|
+
}
|
|
194
229
|
export async function main() {
|
|
195
230
|
const accountId = process.env.MASONS_BROKER_ACCOUNT_ID ?? DEFAULT_ACCOUNT_ID;
|
|
196
231
|
const envApiHost = process.env.MASONS_BROKER_API_HOST;
|
|
@@ -200,6 +235,7 @@ export async function main() {
|
|
|
200
235
|
userDataDir: userDataOverride,
|
|
201
236
|
});
|
|
202
237
|
const logger = createBrokerLogger(paths.logDir);
|
|
238
|
+
installFatalExitHandlers(logger);
|
|
203
239
|
const principal = await resolveRuntimePrincipal(creds.apiHost, creds.token);
|
|
204
240
|
logger.info("broker_entry_starting", {
|
|
205
241
|
accountId: creds.accountId,
|
|
@@ -276,7 +312,12 @@ if (import.meta.url === argvUrl) {
|
|
|
276
312
|
if (err instanceof BrokerAlreadyRunningError) {
|
|
277
313
|
process.exit(0);
|
|
278
314
|
}
|
|
279
|
-
|
|
315
|
+
if (entryLogger) {
|
|
316
|
+
entryLogger.error("broker_entry_fatal", serializeFatalReason(err));
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
console.error("broker_entry_fatal", err);
|
|
320
|
+
}
|
|
280
321
|
process.exit(1);
|
|
281
322
|
});
|
|
282
323
|
}
|
|
@@ -3,6 +3,7 @@ import type { EndpointBackgroundExchangeMode, EndpointExecutionSurface, RuntimeE
|
|
|
3
3
|
import type { BrokerLogger } from "./logger.js";
|
|
4
4
|
import type { NetworkPresence } from "./network-presence.js";
|
|
5
5
|
import type { RuntimeProcessingState, RuntimeWorkTargetRef } from "./runtime-processing-state-event-types.js";
|
|
6
|
+
import { type IpcCapabilities } from "./version-handshake.js";
|
|
6
7
|
export interface IPCServerHandlers {
|
|
7
8
|
registerEndpoint(body: RegisterEndpointBody, ipcWs: WebSocket): Promise<RegisterEndpointResponse>;
|
|
8
9
|
heartbeatEndpoint(endpoint_id: string): Promise<void>;
|
|
@@ -101,8 +102,9 @@ export interface IPCServerOptions {
|
|
|
101
102
|
bearerToken: string;
|
|
102
103
|
handlers: IPCServerHandlers;
|
|
103
104
|
logger: BrokerLogger;
|
|
104
|
-
onChannelOpened?: (plugin_pid: number, ws: WebSocket) => void;
|
|
105
|
+
onChannelOpened?: (plugin_pid: number, ws: WebSocket, clientCapabilities: IpcCapabilities) => void;
|
|
105
106
|
onChannelClosed?: (plugin_pid: number, ws: WebSocket) => void;
|
|
107
|
+
onPushAck?: (plugin_pid: number, ws: WebSocket, push_id: string) => void;
|
|
106
108
|
getNetworkPresence: () => NetworkPresence;
|
|
107
109
|
}
|
|
108
110
|
export interface RunningIPCServer {
|
|
@@ -114,6 +116,7 @@ export declare function startIPCServer(opts: IPCServerOptions): Promise<RunningI
|
|
|
114
116
|
export declare function pushToPlugin(ws: WebSocket, event: PushEvent): boolean;
|
|
115
117
|
export type PushEvent = {
|
|
116
118
|
event: "message_received";
|
|
119
|
+
push_id?: string;
|
|
117
120
|
from: string;
|
|
118
121
|
content: string;
|
|
119
122
|
contentType: string;
|
|
@@ -122,9 +125,11 @@ export type PushEvent = {
|
|
|
122
125
|
runtimeAssignment?: RuntimeAssignmentContext;
|
|
123
126
|
} | {
|
|
124
127
|
event: "ping";
|
|
128
|
+
push_id?: string;
|
|
125
129
|
ts: string;
|
|
126
130
|
} | {
|
|
127
131
|
event: "presence_changed";
|
|
132
|
+
push_id?: string;
|
|
128
133
|
presence: NetworkPresence;
|
|
129
134
|
reason?: string;
|
|
130
135
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ipc-server.d.ts","sourceRoot":"","sources":["../../src/broker/ipc-server.ts"],"names":[],"mappings":"AAyBA,OAAO,EAAE,KAAK,OAAO,EAAE,SAAS,EAAmB,MAAM,IAAI,CAAC;AAC9D,OAAO,KAAK,EACV,8BAA8B,EAC9B,wBAAwB,EACxB,yBAAyB,EAC1B,MAAM,+BAA+B,CAAC;AAEvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EACV,sBAAsB,EACtB,oBAAoB,EACrB,MAAM,2CAA2C,CAAC;
|
|
1
|
+
{"version":3,"file":"ipc-server.d.ts","sourceRoot":"","sources":["../../src/broker/ipc-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -29,7 +29,7 @@ export class BrokerHttpError extends Error {
|
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
export async function startIPCServer(opts) {
|
|
32
|
-
const { bearerToken, handlers, logger, onChannelOpened, onChannelClosed, getNetworkPresence, } = opts;
|
|
32
|
+
const { bearerToken, handlers, logger, onChannelOpened, onChannelClosed, getNetworkPresence, onPushAck, } = opts;
|
|
33
33
|
const http = createServer((req, res) => {
|
|
34
34
|
void routeHttp(req, res, bearerToken, handlers, logger, getNetworkPresence);
|
|
35
35
|
});
|
|
@@ -52,8 +52,17 @@ export async function startIPCServer(opts) {
|
|
|
52
52
|
return;
|
|
53
53
|
}
|
|
54
54
|
wss.handleUpgrade(req, socket, head, (ws) => {
|
|
55
|
-
onChannelOpened?.(pid, ws);
|
|
55
|
+
onChannelOpened?.(pid, ws, readClientCapabilities(req));
|
|
56
56
|
ws.once("close", () => onChannelClosed?.(pid, ws));
|
|
57
|
+
ws.on("message", (data) => {
|
|
58
|
+
const parsed = parsePluginFrame(data);
|
|
59
|
+
if (parsed !== null &&
|
|
60
|
+
typeof parsed === "object" &&
|
|
61
|
+
parsed.event === "push_ack" &&
|
|
62
|
+
typeof parsed.push_id === "string") {
|
|
63
|
+
onPushAck?.(pid, ws, parsed.push_id);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
57
66
|
wss.emit("connection", ws, req);
|
|
58
67
|
});
|
|
59
68
|
});
|
|
@@ -235,6 +244,21 @@ function readPluginPid(req) {
|
|
|
235
244
|
const n = Number.parseInt(str, 10);
|
|
236
245
|
return Number.isFinite(n) && n > 0 ? n : null;
|
|
237
246
|
}
|
|
247
|
+
function readClientCapabilities(req) {
|
|
248
|
+
const raw = req.headers["x-masons-ipc-capabilities"];
|
|
249
|
+
const str = Array.isArray(raw) ? raw.join(",") : raw;
|
|
250
|
+
const tokens = new Set(typeof str === "string"
|
|
251
|
+
? str
|
|
252
|
+
.split(",")
|
|
253
|
+
.map((part) => part.trim())
|
|
254
|
+
.filter(Boolean)
|
|
255
|
+
: []);
|
|
256
|
+
return {
|
|
257
|
+
...(tokens.has("push_receipt_ack_v1") && {
|
|
258
|
+
push_receipt_ack_v1: true,
|
|
259
|
+
}),
|
|
260
|
+
};
|
|
261
|
+
}
|
|
238
262
|
function constantTimeEquals(a, b) {
|
|
239
263
|
if (a.length !== b.length)
|
|
240
264
|
return false;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { NetworkPresence } from "./network-presence.js";
|
|
2
|
-
export declare const IPC_PROTOCOL_VERSION = "1.
|
|
2
|
+
export declare const IPC_PROTOCOL_VERSION = "1.1";
|
|
3
3
|
export interface IpcCapabilities {
|
|
4
4
|
endpoint_metadata_v1?: boolean;
|
|
5
5
|
remote_spawn_v1?: boolean;
|
|
6
6
|
undispatched_inbox_v1?: boolean;
|
|
7
7
|
runtime_assignment_reply_v1?: boolean;
|
|
8
|
+
push_receipt_ack_v1?: boolean;
|
|
8
9
|
}
|
|
9
10
|
export declare const SERVER_CAPABILITIES: Readonly<IpcCapabilities>;
|
|
10
11
|
export interface InitializeRequestBody {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version-handshake.d.ts","sourceRoot":"","sources":["../../src/broker/version-handshake.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAG7D,eAAO,MAAM,oBAAoB,QAAQ,CAAC;AAM1C,MAAM,WAAW,eAAe;IAE9B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAE/B,eAAe,CAAC,EAAE,OAAO,CAAC;IAG1B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAEhC,2BAA2B,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"version-handshake.d.ts","sourceRoot":"","sources":["../../src/broker/version-handshake.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAG7D,eAAO,MAAM,oBAAoB,QAAQ,CAAC;AAM1C,MAAM,WAAW,eAAe;IAE9B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAE/B,eAAe,CAAC,EAAE,OAAO,CAAC;IAG1B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAEhC,2BAA2B,CAAC,EAAE,OAAO,CAAC;IAMtC,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAGD,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CAAC,eAAe,CAMxD,CAAC;AAEH,MAAM,WAAW,qBAAqB;IAEpC,uBAAuB,EAAE,MAAM,CAAC;IAEhC,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,eAAe,CAAC;CAChC;AAED,MAAM,WAAW,sBAAsB;IACrC,uBAAuB,EAAE,MAAM,CAAC;IAChC,mBAAmB,EAAE,eAAe,CAAC;IAErC,UAAU,EAAE,MAAM,CAAC;IAanB,gBAAgB,EAAE,eAAe,CAAC;CACnC;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,2BAA2B,GAAG,aAAa,CAAC;IACnD,OAAO,EAAE,MAAM,CAAC;CACjB;AAUD,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,qBAAqB,EAC1B,GAAG,EAAE;IAAE,eAAe,EAAE,eAAe,CAAA;CAAE,GAEvC;IAAE,MAAM,EAAE,GAAG,CAAC;IAAC,IAAI,EAAE,sBAAsB,CAAA;CAAE,GAC7C;IAAE,MAAM,EAAE,GAAG,CAAC;IAAC,IAAI,EAAE,mBAAmB,CAAA;CAAE,CA2C7C"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
|
-
export const IPC_PROTOCOL_VERSION = "1.
|
|
2
|
+
export const IPC_PROTOCOL_VERSION = "1.1";
|
|
3
3
|
export const SERVER_CAPABILITIES = Object.freeze({
|
|
4
4
|
endpoint_metadata_v1: true,
|
|
5
5
|
remote_spawn_v1: true,
|
|
6
6
|
undispatched_inbox_v1: false,
|
|
7
7
|
runtime_assignment_reply_v1: true,
|
|
8
|
+
push_receipt_ack_v1: true,
|
|
8
9
|
});
|
|
9
10
|
export function handleInitialize(req, ctx) {
|
|
10
11
|
if (typeof req.client_protocol_version !== "string") {
|
|
@@ -26,6 +26,9 @@ export interface BrokerClientConnectOptions {
|
|
|
26
26
|
pluginPid: number;
|
|
27
27
|
clientKind: string;
|
|
28
28
|
clientVersion: string;
|
|
29
|
+
heartbeatIntervalMs?: number;
|
|
30
|
+
heartbeatTimeoutMs?: number;
|
|
31
|
+
heartbeatMissesBeforeDisconnect?: number;
|
|
29
32
|
}
|
|
30
33
|
export interface RegisterEndpointArgs {
|
|
31
34
|
agentId: string;
|
|
@@ -92,6 +95,11 @@ type Events = {
|
|
|
92
95
|
export declare class BrokerClient extends EventEmitter {
|
|
93
96
|
private readonly handle;
|
|
94
97
|
private ws;
|
|
98
|
+
private heartbeatInterval;
|
|
99
|
+
private heartbeatTimeout;
|
|
100
|
+
private heartbeatMisses;
|
|
101
|
+
private heartbeatTimeoutMs;
|
|
102
|
+
private heartbeatMissesBeforeDisconnect;
|
|
95
103
|
private pluginPid;
|
|
96
104
|
private _sessionId;
|
|
97
105
|
private _networkPresence;
|
|
@@ -127,6 +135,11 @@ export declare class BrokerClient extends EventEmitter {
|
|
|
127
135
|
emit(event: string | symbol, ...args: unknown[]): boolean;
|
|
128
136
|
private httpJson;
|
|
129
137
|
private handleFrame;
|
|
138
|
+
private sendPushAck;
|
|
139
|
+
private startHeartbeat;
|
|
140
|
+
private sendHeartbeatProbe;
|
|
141
|
+
private markHeartbeatAlive;
|
|
142
|
+
private clearHeartbeat;
|
|
130
143
|
}
|
|
131
144
|
export {};
|
|
132
145
|
//# sourceMappingURL=broker-client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"broker-client.d.ts","sourceRoot":"","sources":["../../src/broker-client/broker-client.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAErE,OAAO,KAAK,EACV,sBAAsB,EACtB,oBAAoB,EACrB,MAAM,mDAAmD,CAAC;AAC3D,OAAO,EACL,KAAK,sBAAsB,EAE3B,KAAK,eAAe,EACrB,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,EACV,8BAA8B,EAC9B,wBAAwB,EACxB,yBAAyB,EAC1B,MAAM,+BAA+B,CAAC;AAcvC,qBAAa,yBAA0B,SAAQ,KAAK;IAClD,QAAQ,CAAC,IAAI,EAAG,uBAAuB,CAAU;IACjD,QAAQ,CAAC,SAAS,EAAG,IAAI,CAAU;gBACvB,OAAO,EAAE,MAAM;CAI5B;AAOD,qBAAa,gCAAiC,SAAQ,KAAK;IACzD,QAAQ,CAAC,IAAI,EAAG,gCAAgC,CAAU;IAC1D,QAAQ,CAAC,SAAS,EAAG,KAAK,CAAU;gBACxB,OAAO,EAAE,MAAM;CAI5B;AAgBD,MAAM,WAAW,2BAA2B;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IAErB,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,0BAA0B;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"broker-client.d.ts","sourceRoot":"","sources":["../../src/broker-client/broker-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -30,6 +30,11 @@ function safeJsonParse(text) {
|
|
|
30
30
|
export class BrokerClient extends EventEmitter {
|
|
31
31
|
handle;
|
|
32
32
|
ws = null;
|
|
33
|
+
heartbeatInterval = null;
|
|
34
|
+
heartbeatTimeout = null;
|
|
35
|
+
heartbeatMisses = 0;
|
|
36
|
+
heartbeatTimeoutMs = 5_000;
|
|
37
|
+
heartbeatMissesBeforeDisconnect = 2;
|
|
33
38
|
pluginPid = null;
|
|
34
39
|
_sessionId = null;
|
|
35
40
|
_networkPresence = null;
|
|
@@ -81,11 +86,22 @@ export class BrokerClient extends EventEmitter {
|
|
|
81
86
|
this.pluginPid = opts.pluginPid;
|
|
82
87
|
this._clientKind = opts.clientKind;
|
|
83
88
|
this._clientVersion = opts.clientVersion;
|
|
89
|
+
this.heartbeatTimeoutMs = opts.heartbeatTimeoutMs ?? 5_000;
|
|
90
|
+
this.heartbeatMissesBeforeDisconnect =
|
|
91
|
+
opts.heartbeatMissesBeforeDisconnect ?? 2;
|
|
92
|
+
const clientCapabilities = {
|
|
93
|
+
endpoint_metadata_v1: true,
|
|
94
|
+
push_receipt_ack_v1: true,
|
|
95
|
+
};
|
|
96
|
+
const clientCapabilityHeader = Object.entries(clientCapabilities)
|
|
97
|
+
.filter(([, enabled]) => enabled === true)
|
|
98
|
+
.map(([name]) => name)
|
|
99
|
+
.join(",");
|
|
84
100
|
const initRes = await this.httpJson("POST", "/v1/initialize", {
|
|
85
101
|
client_protocol_version: IPC_PROTOCOL_VERSION,
|
|
86
102
|
client_kind: opts.clientKind,
|
|
87
103
|
client_version: opts.clientVersion,
|
|
88
|
-
capabilities:
|
|
104
|
+
capabilities: clientCapabilities,
|
|
89
105
|
});
|
|
90
106
|
this._sessionId = initRes.session_id;
|
|
91
107
|
this._serverCapabilities = initRes.server_capabilities;
|
|
@@ -95,6 +111,7 @@ export class BrokerClient extends EventEmitter {
|
|
|
95
111
|
headers: {
|
|
96
112
|
Authorization: `Bearer ${this.handle.record.bearerToken}`,
|
|
97
113
|
"x-plugin-pid": String(opts.pluginPid),
|
|
114
|
+
"x-masons-ipc-capabilities": clientCapabilityHeader,
|
|
98
115
|
},
|
|
99
116
|
});
|
|
100
117
|
this.ws = ws;
|
|
@@ -111,11 +128,14 @@ export class BrokerClient extends EventEmitter {
|
|
|
111
128
|
ws.once("error", onError);
|
|
112
129
|
});
|
|
113
130
|
ws.on("message", (data) => this.handleFrame(data.toString()));
|
|
131
|
+
ws.on("pong", () => this.markHeartbeatAlive());
|
|
114
132
|
ws.on("close", () => {
|
|
133
|
+
this.clearHeartbeat();
|
|
115
134
|
this.ws = null;
|
|
116
135
|
this.emit("disconnected");
|
|
117
136
|
});
|
|
118
137
|
ws.on("error", (err) => this.emit("error", err));
|
|
138
|
+
this.startHeartbeat(opts.heartbeatIntervalMs ?? 30_000);
|
|
119
139
|
return initRes;
|
|
120
140
|
}
|
|
121
141
|
async registerEndpoint(args) {
|
|
@@ -196,6 +216,7 @@ export class BrokerClient extends EventEmitter {
|
|
|
196
216
|
this.ws.readyState === WebSocket.CONNECTING)) {
|
|
197
217
|
this.ws.close(1000, "client_close");
|
|
198
218
|
}
|
|
219
|
+
this.clearHeartbeat();
|
|
199
220
|
this.ws = null;
|
|
200
221
|
}
|
|
201
222
|
on(event, listener) {
|
|
@@ -258,6 +279,11 @@ export class BrokerClient extends EventEmitter {
|
|
|
258
279
|
}
|
|
259
280
|
if (!parsed || typeof parsed !== "object" || !("event" in parsed))
|
|
260
281
|
return;
|
|
282
|
+
const pushId = parsed.push_id;
|
|
283
|
+
if (typeof pushId === "string" &&
|
|
284
|
+
this._serverCapabilities.push_receipt_ack_v1 === true) {
|
|
285
|
+
this.sendPushAck(pushId);
|
|
286
|
+
}
|
|
261
287
|
const event = parsed.event;
|
|
262
288
|
if (event === "message_received") {
|
|
263
289
|
const msg = parsed;
|
|
@@ -291,4 +317,69 @@ export class BrokerClient extends EventEmitter {
|
|
|
291
317
|
return;
|
|
292
318
|
}
|
|
293
319
|
}
|
|
320
|
+
sendPushAck(pushId) {
|
|
321
|
+
const ws = this.ws;
|
|
322
|
+
if (!ws || ws.readyState !== WebSocket.OPEN)
|
|
323
|
+
return;
|
|
324
|
+
try {
|
|
325
|
+
ws.send(JSON.stringify({ event: "push_ack", push_id: pushId }));
|
|
326
|
+
}
|
|
327
|
+
catch (err) {
|
|
328
|
+
this.emit("error", err instanceof Error ? err : new Error(String(err)));
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
startHeartbeat(intervalMs) {
|
|
332
|
+
this.clearHeartbeat();
|
|
333
|
+
if (!Number.isFinite(intervalMs) || intervalMs <= 0)
|
|
334
|
+
return;
|
|
335
|
+
const timer = setInterval(() => this.sendHeartbeatProbe(), intervalMs);
|
|
336
|
+
const maybeUnref = timer;
|
|
337
|
+
if (typeof maybeUnref.unref === "function")
|
|
338
|
+
maybeUnref.unref();
|
|
339
|
+
this.heartbeatInterval = timer;
|
|
340
|
+
}
|
|
341
|
+
sendHeartbeatProbe() {
|
|
342
|
+
const ws = this.ws;
|
|
343
|
+
if (!ws || ws.readyState !== WebSocket.OPEN)
|
|
344
|
+
return;
|
|
345
|
+
if (this.heartbeatTimeout)
|
|
346
|
+
return;
|
|
347
|
+
try {
|
|
348
|
+
ws.ping();
|
|
349
|
+
}
|
|
350
|
+
catch (err) {
|
|
351
|
+
this.emit("error", err instanceof Error ? err : new Error(String(err)));
|
|
352
|
+
ws.terminate();
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
const timeout = setTimeout(() => {
|
|
356
|
+
this.heartbeatTimeout = null;
|
|
357
|
+
this.heartbeatMisses += 1;
|
|
358
|
+
if (this.heartbeatMisses >= this.heartbeatMissesBeforeDisconnect) {
|
|
359
|
+
ws.terminate();
|
|
360
|
+
}
|
|
361
|
+
}, this.heartbeatTimeoutMs);
|
|
362
|
+
const maybeUnref = timeout;
|
|
363
|
+
if (typeof maybeUnref.unref === "function")
|
|
364
|
+
maybeUnref.unref();
|
|
365
|
+
this.heartbeatTimeout = timeout;
|
|
366
|
+
}
|
|
367
|
+
markHeartbeatAlive() {
|
|
368
|
+
this.heartbeatMisses = 0;
|
|
369
|
+
if (this.heartbeatTimeout) {
|
|
370
|
+
clearTimeout(this.heartbeatTimeout);
|
|
371
|
+
this.heartbeatTimeout = null;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
clearHeartbeat() {
|
|
375
|
+
if (this.heartbeatInterval) {
|
|
376
|
+
clearInterval(this.heartbeatInterval);
|
|
377
|
+
this.heartbeatInterval = null;
|
|
378
|
+
}
|
|
379
|
+
if (this.heartbeatTimeout) {
|
|
380
|
+
clearTimeout(this.heartbeatTimeout);
|
|
381
|
+
this.heartbeatTimeout = null;
|
|
382
|
+
}
|
|
383
|
+
this.heartbeatMisses = 0;
|
|
384
|
+
}
|
|
294
385
|
}
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const PLUGIN_VERSION = "0.2.
|
|
1
|
+
export declare const PLUGIN_VERSION = "0.2.9";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const PLUGIN_VERSION = "0.2.
|
|
1
|
+
export const PLUGIN_VERSION = "0.2.9";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@masons/runtime-broker",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.9",
|
|
4
4
|
"description": "MASONS Runtime Broker — local daemon and BrokerClient SDK for multi-session agent runtime coordination.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "MASONS.ai <hello@masons.ai> (https://masons.ai)",
|