oasis_test 0.1.138 → 0.1.139
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/index.js +78 -11
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -207602,6 +207602,14 @@ var init_daemon_hub = __esm({
|
|
|
207602
207602
|
sessionMeta = /* @__PURE__ */ new Map();
|
|
207603
207603
|
sessionConnectListeners = [];
|
|
207604
207604
|
sessionDisconnectListeners = [];
|
|
207605
|
+
// ── ADR 0300 D2「日志复制」:帧号 + 累积 ackSeq + 幂等摄入 ────────────────────────────
|
|
207606
|
+
// 只对自报 supportsFrameSeq 的会话生效;老会话这三张表始终为空、逐字走原 outbox 语义。
|
|
207607
|
+
/** 自报支持帧号的 dispatchId。 */
|
|
207608
|
+
frameSeqSupported = /* @__PURE__ */ new Set();
|
|
207609
|
+
/** 每 dispatch 已按序摄入的最高节点帧号(累积水位)。跨重连保留、`session_exited` 后延迟清。 */
|
|
207610
|
+
frameWatermark = /* @__PURE__ */ new Map();
|
|
207611
|
+
/** 每 dispatch 上次回 ackSeq 的时刻——把流式期间的回执节流到 ~250ms 一次。 */
|
|
207612
|
+
lastAckSeqAt = /* @__PURE__ */ new Map();
|
|
207605
207613
|
/**
|
|
207606
207614
|
* 「这次派发归谁管、现在什么状态」的认领口。**必须由 hub 汇总,不能各 adapter 自己判**——
|
|
207607
207615
|
* serve 里同时有两个 DaemonHubAdapter(chat 一个、dispatch 一个),一次派发只属于其中一个。
|
|
@@ -207836,12 +207844,33 @@ var init_daemon_hub = __esm({
|
|
|
207836
207844
|
for (const l of this.sessionConnectListeners) l({ dispatchId, sessionId: msg.sessionId, nodeId });
|
|
207837
207845
|
void this.judgeSession(dispatchId, ws);
|
|
207838
207846
|
}
|
|
207847
|
+
if (msg.supportsFrameSeq) {
|
|
207848
|
+
this.frameSeqSupported.add(dispatchId);
|
|
207849
|
+
this.sendAckSeq(ws, dispatchId, true);
|
|
207850
|
+
}
|
|
207839
207851
|
return;
|
|
207840
207852
|
}
|
|
207841
207853
|
if (!registered) {
|
|
207842
207854
|
ws.close(1008, "session_hello required first");
|
|
207843
207855
|
return;
|
|
207844
207856
|
}
|
|
207857
|
+
if (this.frameSeqSupported.has(dispatchId)) {
|
|
207858
|
+
const seq = typeof msg.seq === "number" ? msg.seq : void 0;
|
|
207859
|
+
if (seq !== void 0) {
|
|
207860
|
+
const wm = this.frameWatermark.get(dispatchId) ?? 0;
|
|
207861
|
+
if (seq <= wm) {
|
|
207862
|
+
this.sendAckSeq(ws, dispatchId, false);
|
|
207863
|
+
return;
|
|
207864
|
+
}
|
|
207865
|
+
this.frameWatermark.set(dispatchId, seq);
|
|
207866
|
+
}
|
|
207867
|
+
for (const listener of this.messageListeners) listener(nodeId, msg);
|
|
207868
|
+
this.onMessage?.(nodeId, msg);
|
|
207869
|
+
const isExit = msg.type === "session_exited";
|
|
207870
|
+
this.sendAckSeq(ws, dispatchId, isExit);
|
|
207871
|
+
if (isExit) this.scheduleFrameStateCleanup(dispatchId);
|
|
207872
|
+
return;
|
|
207873
|
+
}
|
|
207845
207874
|
for (const listener of this.messageListeners) listener(nodeId, msg);
|
|
207846
207875
|
this.onMessage?.(nodeId, msg);
|
|
207847
207876
|
if (msg.type === "session_exited" && ws.readyState === import_websocket.default.OPEN) {
|
|
@@ -207857,6 +207886,23 @@ var init_daemon_hub = __esm({
|
|
|
207857
207886
|
});
|
|
207858
207887
|
ws.on("error", (err) => console.error(`[hub] session ${dispatchId} error:`, err.message));
|
|
207859
207888
|
}
|
|
207889
|
+
/** ADR 0300 D2:回带当前摄入水位的累积回执。流式期间节流到 ~250ms 一次,hello / 收尾帧立即回。 */
|
|
207890
|
+
sendAckSeq(ws, dispatchId, force) {
|
|
207891
|
+
if (ws.readyState !== import_websocket.default.OPEN) return;
|
|
207892
|
+
const now = Date.now();
|
|
207893
|
+
if (!force && now - (this.lastAckSeqAt.get(dispatchId) ?? 0) < 250) return;
|
|
207894
|
+
this.lastAckSeqAt.set(dispatchId, now);
|
|
207895
|
+
ws.send(JSON.stringify({ type: "ack", dispatchId, ackSeq: this.frameWatermark.get(dispatchId) ?? 0 }));
|
|
207896
|
+
}
|
|
207897
|
+
/** `session_exited` 后延迟清帧号状态:给重连重放的收尾帧留一个去重窗口,之后回收避免无界增长。 */
|
|
207898
|
+
scheduleFrameStateCleanup(dispatchId) {
|
|
207899
|
+
const t = setTimeout(() => {
|
|
207900
|
+
this.frameSeqSupported.delete(dispatchId);
|
|
207901
|
+
this.frameWatermark.delete(dispatchId);
|
|
207902
|
+
this.lastAckSeqAt.delete(dispatchId);
|
|
207903
|
+
}, 6e4);
|
|
207904
|
+
t.unref?.();
|
|
207905
|
+
}
|
|
207860
207906
|
/**
|
|
207861
207907
|
* 注册一个认领判断。返回:
|
|
207862
207908
|
* live —— 这次派发在我这儿还活着(别动它)
|
|
@@ -239527,6 +239573,8 @@ async function runSession(dispatchId, job, deps) {
|
|
|
239527
239573
|
var RECONNECT_MIN_MS = 1e3;
|
|
239528
239574
|
var RECONNECT_MAX_MS = 3e4;
|
|
239529
239575
|
var EXIT_ACK_WAIT_MS = LINK_WINDOWS.exitAckWaitMs;
|
|
239576
|
+
var OUTBOX_MAX_FRAMES = 8e3;
|
|
239577
|
+
var isKeyFrame = (m2) => m2.type === "session_started" || m2.type === "session_exited";
|
|
239530
239578
|
async function runSessionProcess(specFile, adapter) {
|
|
239531
239579
|
process.env["OASIS_BIND_RUNTIME_PDEATHSIG"] = "1";
|
|
239532
239580
|
const spec = readSpec(specFile);
|
|
@@ -239582,6 +239630,10 @@ var SessionProcessState = class {
|
|
|
239582
239630
|
* 而会话其实正在跑。
|
|
239583
239631
|
*/
|
|
239584
239632
|
outbox = [];
|
|
239633
|
+
/** ADR 0300 D2:每 dispatch 单调帧号,任何副作用之前分配。 */
|
|
239634
|
+
frameSeq = 0;
|
|
239635
|
+
/** 收到过带 `ackSeq` 的 ack = 本服务端会按帧号去重;只有它为真,重连才敢重放**全部**帧(含输出)。 */
|
|
239636
|
+
serverSupportsDedup = false;
|
|
239585
239637
|
/** append_input 串行链——保证回帧次序 = 到达次序(server 侧按 FIFO 认领等待者)。 */
|
|
239586
239638
|
appendChain = Promise.resolve();
|
|
239587
239639
|
async run() {
|
|
@@ -239647,9 +239699,12 @@ var SessionProcessState = class {
|
|
|
239647
239699
|
daemonVersion: this.spec.daemonVersion,
|
|
239648
239700
|
// 自报身份要够服务端对上账:chat 道的对账键是 artifactId(run.id=chat-run:* ≠ dispatchId),
|
|
239649
239701
|
// 只报 dispatchId 的话 serve 重启后它认不出这是条活会话,会当成野进程 evict 掉。
|
|
239650
|
-
...this.spec.job.artifactId ? { jobArtifactId: this.spec.job.artifactId } : {}
|
|
239702
|
+
...this.spec.job.artifactId ? { jobArtifactId: this.spec.job.artifactId } : {},
|
|
239703
|
+
// ADR 0300 D2:自报支持帧号;新服务端据此回带 ackSeq 的 hello-ack,届时才把 serverSupportsDedup 置真。
|
|
239704
|
+
supportsFrameSeq: true
|
|
239651
239705
|
});
|
|
239652
|
-
|
|
239706
|
+
const toResend = this.serverSupportsDedup ? this.outbox : this.outbox.filter(isKeyFrame);
|
|
239707
|
+
for (const m2 of toResend) this.rawSend(m2);
|
|
239653
239708
|
});
|
|
239654
239709
|
ws.on("message", (raw) => {
|
|
239655
239710
|
let msg;
|
|
@@ -239697,8 +239752,14 @@ var SessionProcessState = class {
|
|
|
239697
239752
|
}
|
|
239698
239753
|
case "ack":
|
|
239699
239754
|
if (msg.dispatchId !== this.spec.dispatchId) return;
|
|
239700
|
-
|
|
239701
|
-
|
|
239755
|
+
if (typeof msg.ackSeq === "number") {
|
|
239756
|
+
this.serverSupportsDedup = true;
|
|
239757
|
+
const wm = msg.ackSeq;
|
|
239758
|
+
this.outbox = this.outbox.filter((f2) => (f2.seq ?? 0) > wm);
|
|
239759
|
+
} else {
|
|
239760
|
+
this.outbox.length = 0;
|
|
239761
|
+
}
|
|
239762
|
+
if (this.outbox.length === 0) this.exitAckResolve?.();
|
|
239702
239763
|
return;
|
|
239703
239764
|
case "ping":
|
|
239704
239765
|
this.rawSend({ type: "pong" });
|
|
@@ -239713,14 +239774,20 @@ var SessionProcessState = class {
|
|
|
239713
239774
|
this.ws.send(JSON.stringify(msg));
|
|
239714
239775
|
return true;
|
|
239715
239776
|
}
|
|
239716
|
-
/**
|
|
239777
|
+
/** ADR 0300 D2:给帧派单调 seq、进 outbox(超上限丢最老)、再尽力发。返回带 seq 的帧。 */
|
|
239778
|
+
stampAndBuffer(msg) {
|
|
239779
|
+
const framed = { ...msg, seq: ++this.frameSeq };
|
|
239780
|
+
this.outbox.push(framed);
|
|
239781
|
+
if (this.outbox.length > OUTBOX_MAX_FRAMES) this.outbox.splice(0, this.outbox.length - OUTBOX_MAX_FRAMES);
|
|
239782
|
+
return framed;
|
|
239783
|
+
}
|
|
239784
|
+
/** 关键帧(started/exited):必达,进 outbox,ack 到达(按 ackSeq 或整清)才删。 */
|
|
239717
239785
|
sendKeyFrame(msg) {
|
|
239718
|
-
this.
|
|
239719
|
-
this.rawSend(msg);
|
|
239786
|
+
this.rawSend(this.stampAndBuffer(msg));
|
|
239720
239787
|
}
|
|
239721
|
-
/**
|
|
239788
|
+
/** 输出/事件帧:ADR 0300 D2 起也进 outbox 带 seq——断线期不再丢;服务端按 ackSeq 累积回执后即从 outbox 排掉。 */
|
|
239722
239789
|
sendStream(msg) {
|
|
239723
|
-
this.rawSend(msg);
|
|
239790
|
+
this.rawSend(this.stampAndBuffer(msg));
|
|
239724
239791
|
}
|
|
239725
239792
|
// ── 看门狗(D2′.5 防线 3 + 防线 1 后半)──────────────────────────────────
|
|
239726
239793
|
startWatchdog() {
|
|
@@ -239745,7 +239812,7 @@ var SessionProcessState = class {
|
|
|
239745
239812
|
await this.handle?.kill();
|
|
239746
239813
|
} catch {
|
|
239747
239814
|
}
|
|
239748
|
-
this.
|
|
239815
|
+
this.sendKeyFrame({
|
|
239749
239816
|
type: "session_exited",
|
|
239750
239817
|
dispatchId: this.spec.dispatchId,
|
|
239751
239818
|
sessionId: this.handle?.id ?? this.spec.dispatchId,
|
|
@@ -245934,7 +246001,7 @@ function shimScript() {
|
|
|
245934
246001
|
}
|
|
245935
246002
|
|
|
245936
246003
|
// src/index.ts
|
|
245937
|
-
var PKG_VERSION = true ? "0.1.
|
|
246004
|
+
var PKG_VERSION = true ? "0.1.139" : "dev";
|
|
245938
246005
|
var LOCAL_BIN = localBin();
|
|
245939
246006
|
var NPM_PREFIX = npmPrefix();
|
|
245940
246007
|
var INSTANCE = DEFAULT_INSTANCE;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oasis_test",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.139",
|
|
4
4
|
"description": "Oasis node daemon + CLI — background daemon, auto-start, full server CLI",
|
|
5
5
|
"bin": {
|
|
6
6
|
"oasis": "./dist/index.js"
|
|
@@ -26,6 +26,6 @@
|
|
|
26
26
|
"node": ">=20"
|
|
27
27
|
},
|
|
28
28
|
"oasisRelease": {
|
|
29
|
-
"sourceHead": "
|
|
29
|
+
"sourceHead": "6e30e49a710877550f9986ad669c0b9ce7de5f74"
|
|
30
30
|
}
|
|
31
31
|
}
|