@linzumi/cli 0.0.102-beta → 0.0.103-beta
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 +1 -1
- package/dist/index.js +266 -147
- package/package.json +1 -1
package/README.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -3634,7 +3634,7 @@ async function connectPhoenixClient(baseUrl, token, socketFactory = (url, protoc
|
|
|
3634
3634
|
}
|
|
3635
3635
|
dispatchPushedFrame(topic, name, ref, payload);
|
|
3636
3636
|
};
|
|
3637
|
-
const pushOnOpenSocket = (topic, event, payload, timeoutMs = pushTimeoutMs) => {
|
|
3637
|
+
const pushOnOpenSocket = (topic, event, payload, timeoutMs = pushTimeoutMs, onSent) => {
|
|
3638
3638
|
const websocket = state.websocket;
|
|
3639
3639
|
if (websocket === void 0 || websocket.readyState !== WebSocket.OPEN) {
|
|
3640
3640
|
return Promise.reject(phoenixPushErrors.socketNotOpen());
|
|
@@ -3655,6 +3655,7 @@ async function connectPhoenixClient(baseUrl, token, socketFactory = (url, protoc
|
|
|
3655
3655
|
}, replyBudgetMs);
|
|
3656
3656
|
pending.set(ref, { event, timer, resolve: resolve12, reject });
|
|
3657
3657
|
websocket.send(JSON.stringify(frame));
|
|
3658
|
+
onSent?.();
|
|
3658
3659
|
});
|
|
3659
3660
|
};
|
|
3660
3661
|
const mergedJoinPayload = (topic, payloads) => {
|
|
@@ -3867,10 +3868,16 @@ async function connectPhoenixClient(baseUrl, token, socketFactory = (url, protoc
|
|
|
3867
3868
|
}
|
|
3868
3869
|
);
|
|
3869
3870
|
});
|
|
3870
|
-
const push = async (topic, event, payload) => {
|
|
3871
|
+
const push = async (topic, event, payload, onSent) => {
|
|
3871
3872
|
const deadlineMs = Date.now() + pushTimeoutMs;
|
|
3872
3873
|
await awaitReady(event, deadlineMs);
|
|
3873
|
-
return pushOnOpenSocket(
|
|
3874
|
+
return pushOnOpenSocket(
|
|
3875
|
+
topic,
|
|
3876
|
+
event,
|
|
3877
|
+
payload,
|
|
3878
|
+
deadlineMs - Date.now(),
|
|
3879
|
+
onSent
|
|
3880
|
+
);
|
|
3874
3881
|
};
|
|
3875
3882
|
return {
|
|
3876
3883
|
join: async (topic, payload, options2) => {
|
|
@@ -4548,10 +4555,15 @@ function createThreadOutbox(options) {
|
|
|
4548
4555
|
let paused = false;
|
|
4549
4556
|
let acceptingEnqueues = true;
|
|
4550
4557
|
let stopped = false;
|
|
4551
|
-
let drainPromise;
|
|
4552
|
-
let wakeSleep;
|
|
4553
4558
|
let closePromise;
|
|
4554
4559
|
let journal;
|
|
4560
|
+
const maxInFlightPushes = Math.max(
|
|
4561
|
+
1,
|
|
4562
|
+
Math.floor(options.maxInFlightPushes ?? 1)
|
|
4563
|
+
);
|
|
4564
|
+
let inFlightCount = 0;
|
|
4565
|
+
let drainIdleWaiters = [];
|
|
4566
|
+
let sendChainTail = Promise.resolve();
|
|
4555
4567
|
const headEntry = () => queue[headIndex];
|
|
4556
4568
|
const depth = () => queue.length - headIndex;
|
|
4557
4569
|
const currentCounters = () => ({
|
|
@@ -4661,44 +4673,90 @@ function createThreadOutbox(options) {
|
|
|
4661
4673
|
coalescible.delete(key);
|
|
4662
4674
|
}
|
|
4663
4675
|
};
|
|
4664
|
-
const
|
|
4676
|
+
const applyHeadOutcome = (pending, outcome) => {
|
|
4677
|
+
const entry = pending.entry;
|
|
4678
|
+
switch (outcome.kind) {
|
|
4679
|
+
case "ack": {
|
|
4680
|
+
const builder = builders[entry.kind];
|
|
4681
|
+
try {
|
|
4682
|
+
builder?.onReply?.(entry.data, outcome.reply, context);
|
|
4683
|
+
} catch (error) {
|
|
4684
|
+
log2("outbox_on_reply_failed", {
|
|
4685
|
+
threadKey,
|
|
4686
|
+
entrySeq: entry.entrySeq,
|
|
4687
|
+
kind: entry.kind,
|
|
4688
|
+
error: errorMessage2(error)
|
|
4689
|
+
});
|
|
4690
|
+
}
|
|
4691
|
+
journal?.appendAck(entry.entrySeq);
|
|
4692
|
+
break;
|
|
4693
|
+
}
|
|
4694
|
+
case "skip": {
|
|
4695
|
+
log2("outbox_entry_skipped", {
|
|
4696
|
+
threadKey,
|
|
4697
|
+
entrySeq: entry.entrySeq,
|
|
4698
|
+
kind: entry.kind,
|
|
4699
|
+
reason: outcome.reason
|
|
4700
|
+
});
|
|
4701
|
+
journal?.appendSkip(entry.entrySeq, outcome.reason);
|
|
4702
|
+
break;
|
|
4703
|
+
}
|
|
4704
|
+
case "fail": {
|
|
4705
|
+
if (entry.resolution === "must_ack") {
|
|
4706
|
+
journal?.appendFail(entry.entrySeq);
|
|
4707
|
+
try {
|
|
4708
|
+
onPermanentFailure(entry, outcome.failure);
|
|
4709
|
+
} catch (error) {
|
|
4710
|
+
log2("outbox_permanent_failure_callback_failed", {
|
|
4711
|
+
threadKey,
|
|
4712
|
+
entrySeq: entry.entrySeq,
|
|
4713
|
+
error: errorMessage2(error)
|
|
4714
|
+
});
|
|
4715
|
+
}
|
|
4716
|
+
} else {
|
|
4717
|
+
journal?.appendDrop(entry.entrySeq);
|
|
4718
|
+
}
|
|
4719
|
+
break;
|
|
4720
|
+
}
|
|
4721
|
+
}
|
|
4665
4722
|
removeFromCoalescible(pending);
|
|
4666
4723
|
advanceHead();
|
|
4667
4724
|
notifyFlushWaiters();
|
|
4668
4725
|
};
|
|
4669
|
-
const
|
|
4726
|
+
const settleContiguousPrefix = () => {
|
|
4727
|
+
while (true) {
|
|
4728
|
+
const head = headEntry();
|
|
4729
|
+
if (head === void 0 || head.outcome === void 0) {
|
|
4730
|
+
return;
|
|
4731
|
+
}
|
|
4732
|
+
applyHeadOutcome(head, head.outcome);
|
|
4733
|
+
}
|
|
4734
|
+
};
|
|
4735
|
+
const recordOutcome = (pending, outcome) => {
|
|
4670
4736
|
const entry = pending.entry;
|
|
4671
|
-
if (
|
|
4672
|
-
|
|
4673
|
-
|
|
4674
|
-
|
|
4675
|
-
entrySeq: entry.entrySeq,
|
|
4676
|
-
kind: entry.kind,
|
|
4677
|
-
attempts: entry.attempts,
|
|
4678
|
-
error: failure.message
|
|
4679
|
-
});
|
|
4680
|
-
journal?.appendFail(entry.entrySeq);
|
|
4681
|
-
try {
|
|
4682
|
-
onPermanentFailure(entry, failure);
|
|
4683
|
-
} catch (error) {
|
|
4684
|
-
log2("outbox_permanent_failure_callback_failed", {
|
|
4737
|
+
if (outcome.kind === "fail") {
|
|
4738
|
+
if (entry.resolution === "must_ack") {
|
|
4739
|
+
totalPermanentFailures += 1;
|
|
4740
|
+
log2("outbox_permanent_failure", {
|
|
4685
4741
|
threadKey,
|
|
4686
4742
|
entrySeq: entry.entrySeq,
|
|
4687
|
-
|
|
4743
|
+
kind: entry.kind,
|
|
4744
|
+
attempts: entry.attempts,
|
|
4745
|
+
error: outcome.failure.message
|
|
4746
|
+
});
|
|
4747
|
+
} else {
|
|
4748
|
+
totalDroppedBestEffort += 1;
|
|
4749
|
+
log2("outbox_dropped_best_effort", {
|
|
4750
|
+
threadKey,
|
|
4751
|
+
entrySeq: entry.entrySeq,
|
|
4752
|
+
kind: entry.kind,
|
|
4753
|
+
attempts: entry.attempts,
|
|
4754
|
+
error: outcome.failure.message
|
|
4688
4755
|
});
|
|
4689
4756
|
}
|
|
4690
|
-
} else {
|
|
4691
|
-
totalDroppedBestEffort += 1;
|
|
4692
|
-
log2("outbox_dropped_best_effort", {
|
|
4693
|
-
threadKey,
|
|
4694
|
-
entrySeq: entry.entrySeq,
|
|
4695
|
-
kind: entry.kind,
|
|
4696
|
-
attempts: entry.attempts,
|
|
4697
|
-
error: failure.message
|
|
4698
|
-
});
|
|
4699
|
-
journal?.appendDrop(entry.entrySeq);
|
|
4700
4757
|
}
|
|
4701
|
-
|
|
4758
|
+
pending.outcome = outcome;
|
|
4759
|
+
pending.state = "queued";
|
|
4702
4760
|
};
|
|
4703
4761
|
const recordPushLatency = (latencyMs) => {
|
|
4704
4762
|
if (pushLatencyWindow.length < outboxPushLatencyWindowSize) {
|
|
@@ -4708,136 +4766,180 @@ function createThreadOutbox(options) {
|
|
|
4708
4766
|
}
|
|
4709
4767
|
pushLatencyNextIndex = (pushLatencyNextIndex + 1) % outboxPushLatencyWindowSize;
|
|
4710
4768
|
};
|
|
4711
|
-
const
|
|
4712
|
-
|
|
4713
|
-
|
|
4714
|
-
|
|
4715
|
-
}
|
|
4716
|
-
|
|
4717
|
-
|
|
4718
|
-
|
|
4769
|
+
const clearRetryTimer = (pending) => {
|
|
4770
|
+
if (pending.retryTimer !== void 0) {
|
|
4771
|
+
clearTimeout(pending.retryTimer);
|
|
4772
|
+
pending.retryTimer = void 0;
|
|
4773
|
+
}
|
|
4774
|
+
};
|
|
4775
|
+
const notifyDrainIdle = () => {
|
|
4776
|
+
if (inFlightCount > 0) {
|
|
4777
|
+
return;
|
|
4778
|
+
}
|
|
4779
|
+
const waiters = drainIdleWaiters;
|
|
4780
|
+
drainIdleWaiters = [];
|
|
4781
|
+
for (const resolve12 of waiters) {
|
|
4719
4782
|
resolve12();
|
|
4720
|
-
}
|
|
4721
|
-
}
|
|
4722
|
-
const
|
|
4783
|
+
}
|
|
4784
|
+
};
|
|
4785
|
+
const headInBackoff = () => {
|
|
4786
|
+
const head = headEntry();
|
|
4787
|
+
return head !== void 0 && head.outcome === void 0 && head.state === "queued" && head.retryTimer !== void 0;
|
|
4788
|
+
};
|
|
4789
|
+
const scheduleRetry = (pending, delayMs) => {
|
|
4790
|
+
clearRetryTimer(pending);
|
|
4791
|
+
pending.retryTimer = setTimeout(() => {
|
|
4792
|
+
pending.retryTimer = void 0;
|
|
4793
|
+
if (stopped || paused || pending.outcome !== void 0) {
|
|
4794
|
+
return;
|
|
4795
|
+
}
|
|
4796
|
+
pumpWindow();
|
|
4797
|
+
}, delayMs);
|
|
4798
|
+
pending.retryTimer?.unref?.();
|
|
4799
|
+
};
|
|
4800
|
+
const pushEntry = async (pending) => {
|
|
4723
4801
|
const entry = pending.entry;
|
|
4724
|
-
|
|
4802
|
+
const sendTurn = sendChainTail;
|
|
4803
|
+
let releaseSendChain = () => void 0;
|
|
4804
|
+
sendChainTail = new Promise((resolve12) => {
|
|
4805
|
+
releaseSendChain = resolve12;
|
|
4806
|
+
});
|
|
4807
|
+
let released = false;
|
|
4808
|
+
const releaseSend = () => {
|
|
4809
|
+
if (!released) {
|
|
4810
|
+
released = true;
|
|
4811
|
+
releaseSendChain();
|
|
4812
|
+
}
|
|
4813
|
+
};
|
|
4814
|
+
pending.state = "pushing";
|
|
4815
|
+
inFlightCount += 1;
|
|
4816
|
+
try {
|
|
4817
|
+
await sendTurn;
|
|
4818
|
+
if (stopped || paused || pending.outcome !== void 0) {
|
|
4819
|
+
pending.state = "queued";
|
|
4820
|
+
releaseSend();
|
|
4821
|
+
return;
|
|
4822
|
+
}
|
|
4725
4823
|
const builder = builders[entry.kind];
|
|
4726
4824
|
if (builder === void 0) {
|
|
4727
|
-
|
|
4728
|
-
|
|
4729
|
-
|
|
4730
|
-
|
|
4825
|
+
releaseSend();
|
|
4826
|
+
recordOutcome(pending, {
|
|
4827
|
+
kind: "fail",
|
|
4828
|
+
failure: new Error(
|
|
4829
|
+
`no outbox builder registered for kind ${entry.kind}`
|
|
4830
|
+
)
|
|
4831
|
+
});
|
|
4731
4832
|
return;
|
|
4732
4833
|
}
|
|
4733
4834
|
let built;
|
|
4734
4835
|
try {
|
|
4735
4836
|
built = builder.build(entry.data, context);
|
|
4736
4837
|
} catch (error) {
|
|
4737
|
-
|
|
4838
|
+
releaseSend();
|
|
4839
|
+
recordOutcome(pending, { kind: "fail", failure: toError(error) });
|
|
4738
4840
|
return;
|
|
4739
4841
|
}
|
|
4740
4842
|
if ("skip" in built) {
|
|
4741
|
-
|
|
4843
|
+
releaseSend();
|
|
4844
|
+
recordOutcome(pending, { kind: "skip", reason: built.reason });
|
|
4845
|
+
return;
|
|
4846
|
+
}
|
|
4847
|
+
entry.attempts += 1;
|
|
4848
|
+
await pushBuilt(pending, built, releaseSend);
|
|
4849
|
+
} finally {
|
|
4850
|
+
inFlightCount -= 1;
|
|
4851
|
+
}
|
|
4852
|
+
};
|
|
4853
|
+
const pushBuilt = async (pending, built, releaseSend) => {
|
|
4854
|
+
const entry = pending.entry;
|
|
4855
|
+
const pushStartedAtMs = now();
|
|
4856
|
+
try {
|
|
4857
|
+
const reply = await options.push(
|
|
4858
|
+
built.event,
|
|
4859
|
+
built.payload,
|
|
4860
|
+
built.timeoutMs,
|
|
4861
|
+
releaseSend
|
|
4862
|
+
);
|
|
4863
|
+
releaseSend();
|
|
4864
|
+
recordPushLatency(Math.max(0, now() - pushStartedAtMs));
|
|
4865
|
+
totalAcked += 1;
|
|
4866
|
+
recordOutcome(pending, { kind: "ack", reply });
|
|
4867
|
+
} catch (error) {
|
|
4868
|
+
releaseSend();
|
|
4869
|
+
pending.state = "queued";
|
|
4870
|
+
const failure = toError(error);
|
|
4871
|
+
if (options.isRetryBudgetExempt?.(failure) === true) {
|
|
4872
|
+
entry.attempts -= 1;
|
|
4873
|
+
totalRetried += 1;
|
|
4874
|
+
log2("outbox_push_connection_wait", {
|
|
4742
4875
|
threadKey,
|
|
4743
4876
|
entrySeq: entry.entrySeq,
|
|
4744
4877
|
kind: entry.kind,
|
|
4745
|
-
|
|
4878
|
+
error: failure.message
|
|
4746
4879
|
});
|
|
4747
|
-
|
|
4748
|
-
|
|
4749
|
-
|
|
4750
|
-
}
|
|
4751
|
-
|
|
4752
|
-
|
|
4753
|
-
|
|
4754
|
-
|
|
4755
|
-
try {
|
|
4756
|
-
reply = await options.push(built.event, built.payload, built.timeoutMs);
|
|
4757
|
-
} catch (error) {
|
|
4758
|
-
pending.state = "queued";
|
|
4759
|
-
const failure = toError(error);
|
|
4760
|
-
if (options.isRetryBudgetExempt?.(failure) === true) {
|
|
4761
|
-
entry.attempts -= 1;
|
|
4880
|
+
if (!stopped && !paused) {
|
|
4881
|
+
scheduleRetry(pending, budgetExemptRetryFallbackDelayMs);
|
|
4882
|
+
}
|
|
4883
|
+
} else {
|
|
4884
|
+
const delayMs = retryDelaysMs[entry.attempts - 1];
|
|
4885
|
+
if (delayMs === void 0) {
|
|
4886
|
+
recordOutcome(pending, { kind: "fail", failure });
|
|
4887
|
+
} else {
|
|
4762
4888
|
totalRetried += 1;
|
|
4763
|
-
log2("
|
|
4889
|
+
log2("outbox_push_retry", {
|
|
4764
4890
|
threadKey,
|
|
4765
4891
|
entrySeq: entry.entrySeq,
|
|
4766
4892
|
kind: entry.kind,
|
|
4893
|
+
attempt: entry.attempts,
|
|
4894
|
+
delayMs,
|
|
4767
4895
|
error: failure.message
|
|
4768
4896
|
});
|
|
4769
|
-
if (stopped
|
|
4770
|
-
|
|
4771
|
-
}
|
|
4772
|
-
await sleep2(budgetExemptRetryFallbackDelayMs);
|
|
4773
|
-
if (stopped || paused) {
|
|
4774
|
-
return;
|
|
4897
|
+
if (!stopped && !paused) {
|
|
4898
|
+
scheduleRetry(pending, delayMs);
|
|
4775
4899
|
}
|
|
4776
|
-
continue;
|
|
4777
|
-
}
|
|
4778
|
-
const delayMs = retryDelaysMs[entry.attempts - 1];
|
|
4779
|
-
if (delayMs === void 0) {
|
|
4780
|
-
settleFailure(pending, failure);
|
|
4781
|
-
return;
|
|
4782
|
-
}
|
|
4783
|
-
totalRetried += 1;
|
|
4784
|
-
log2("outbox_push_retry", {
|
|
4785
|
-
threadKey,
|
|
4786
|
-
entrySeq: entry.entrySeq,
|
|
4787
|
-
kind: entry.kind,
|
|
4788
|
-
attempt: entry.attempts,
|
|
4789
|
-
delayMs,
|
|
4790
|
-
error: failure.message
|
|
4791
|
-
});
|
|
4792
|
-
await sleep2(delayMs);
|
|
4793
|
-
if (stopped || paused) {
|
|
4794
|
-
return;
|
|
4795
4900
|
}
|
|
4796
|
-
continue;
|
|
4797
4901
|
}
|
|
4798
|
-
pending.state = "queued";
|
|
4799
|
-
try {
|
|
4800
|
-
builder.onReply?.(entry.data, reply, context);
|
|
4801
|
-
} catch (error) {
|
|
4802
|
-
log2("outbox_on_reply_failed", {
|
|
4803
|
-
threadKey,
|
|
4804
|
-
entrySeq: entry.entrySeq,
|
|
4805
|
-
kind: entry.kind,
|
|
4806
|
-
error: errorMessage2(error)
|
|
4807
|
-
});
|
|
4808
|
-
}
|
|
4809
|
-
totalAcked += 1;
|
|
4810
|
-
recordPushLatency(Math.max(0, now() - pushStartedAtMs));
|
|
4811
|
-
journal?.appendAck(entry.entrySeq);
|
|
4812
|
-
settleHead(pending);
|
|
4813
|
-
return;
|
|
4814
4902
|
}
|
|
4815
4903
|
};
|
|
4816
|
-
const
|
|
4817
|
-
|
|
4818
|
-
|
|
4819
|
-
|
|
4820
|
-
|
|
4821
|
-
|
|
4904
|
+
const pumpWindow = () => {
|
|
4905
|
+
settleContiguousPrefix();
|
|
4906
|
+
if (stopped || paused) {
|
|
4907
|
+
notifyDrainIdle();
|
|
4908
|
+
return;
|
|
4909
|
+
}
|
|
4910
|
+
if (headInBackoff()) {
|
|
4911
|
+
notifyDrainIdle();
|
|
4912
|
+
return;
|
|
4913
|
+
}
|
|
4914
|
+
for (let index = headIndex; index < queue.length && inFlightCount < maxInFlightPushes; index += 1) {
|
|
4915
|
+
const pending = queue[index];
|
|
4916
|
+
if (pending === void 0 || pending.outcome !== void 0 || pending.state === "pushing" || pending.retryTimer !== void 0) {
|
|
4917
|
+
continue;
|
|
4822
4918
|
}
|
|
4823
|
-
|
|
4919
|
+
void pushEntry(pending).then(
|
|
4920
|
+
() => pumpWindow(),
|
|
4921
|
+
(error) => {
|
|
4922
|
+
log2("outbox_drain_loop_error", {
|
|
4923
|
+
threadKey,
|
|
4924
|
+
error: errorMessage2(error)
|
|
4925
|
+
});
|
|
4926
|
+
pumpWindow();
|
|
4927
|
+
}
|
|
4928
|
+
);
|
|
4824
4929
|
}
|
|
4930
|
+
notifyDrainIdle();
|
|
4825
4931
|
};
|
|
4826
4932
|
const ensureDraining = () => {
|
|
4827
|
-
if (
|
|
4933
|
+
if (paused || stopped) {
|
|
4828
4934
|
return;
|
|
4829
4935
|
}
|
|
4830
4936
|
if (headEntry() === void 0) {
|
|
4831
4937
|
return;
|
|
4832
4938
|
}
|
|
4833
|
-
|
|
4834
|
-
|
|
4835
|
-
|
|
4836
|
-
|
|
4837
|
-
});
|
|
4838
|
-
}).finally(() => {
|
|
4839
|
-
drainPromise = void 0;
|
|
4840
|
-
ensureDraining();
|
|
4939
|
+
void Promise.resolve().then(() => {
|
|
4940
|
+
if (!stopped && !paused) {
|
|
4941
|
+
pumpWindow();
|
|
4942
|
+
}
|
|
4841
4943
|
});
|
|
4842
4944
|
};
|
|
4843
4945
|
const flush = (timeoutMs) => {
|
|
@@ -4881,10 +4983,16 @@ function createThreadOutbox(options) {
|
|
|
4881
4983
|
});
|
|
4882
4984
|
}
|
|
4883
4985
|
stopped = true;
|
|
4884
|
-
|
|
4885
|
-
|
|
4886
|
-
|
|
4887
|
-
|
|
4986
|
+
for (let index = headIndex; index < queue.length; index += 1) {
|
|
4987
|
+
clearRetryTimer(queue[index]);
|
|
4988
|
+
}
|
|
4989
|
+
if (inFlightCount > 0) {
|
|
4990
|
+
await Promise.race([
|
|
4991
|
+
new Promise((resolve12) => {
|
|
4992
|
+
drainIdleWaiters.push(resolve12);
|
|
4993
|
+
}),
|
|
4994
|
+
sleepUncancellable(closeDrainGraceMs)
|
|
4995
|
+
]);
|
|
4888
4996
|
}
|
|
4889
4997
|
for (const waiter of flushWaiters.splice(0)) {
|
|
4890
4998
|
if (waiter.timer !== void 0) {
|
|
@@ -4903,7 +5011,7 @@ function createThreadOutbox(options) {
|
|
|
4903
5011
|
if (input.coalesceKey !== void 0) {
|
|
4904
5012
|
const key = coalesceMapKey(input.kind, input.coalesceKey);
|
|
4905
5013
|
const existing = coalescible.get(key);
|
|
4906
|
-
if (existing !== void 0 && existing.state === "queued") {
|
|
5014
|
+
if (existing !== void 0 && existing.state === "queued" && existing.outcome === void 0) {
|
|
4907
5015
|
existing.entry.data = coalesceEntryData(
|
|
4908
5016
|
builders[input.kind],
|
|
4909
5017
|
existing.entry,
|
|
@@ -4948,9 +5056,9 @@ function createThreadOutbox(options) {
|
|
|
4948
5056
|
const pending = queue[index];
|
|
4949
5057
|
if (pending !== void 0) {
|
|
4950
5058
|
pending.entry.attempts = 0;
|
|
5059
|
+
clearRetryTimer(pending);
|
|
4951
5060
|
}
|
|
4952
5061
|
}
|
|
4953
|
-
wakeSleep?.();
|
|
4954
5062
|
ensureDraining();
|
|
4955
5063
|
},
|
|
4956
5064
|
metrics: () => {
|
|
@@ -6619,6 +6727,7 @@ function createSessionPipeline(host) {
|
|
|
6619
6727
|
builders,
|
|
6620
6728
|
...host.persistDir === void 0 ? {} : { persistDir: host.persistDir },
|
|
6621
6729
|
...host.outboxRetryDelaysMs === void 0 ? {} : { retryDelaysMs: [...host.outboxRetryDelaysMs] },
|
|
6730
|
+
maxInFlightPushes: host.outboxMaxInFlightPushes ?? defaultOutboxMaxInFlightPushes,
|
|
6622
6731
|
...host.journalRecoveryMaxAgeMs === void 0 ? {} : { journalRecoveryMaxAgeMs: host.journalRecoveryMaxAgeMs },
|
|
6623
6732
|
// Budget semantics (pre-merge review finding 6): wait_for_connection
|
|
6624
6733
|
// failures never consume retry budget - the push never reached the
|
|
@@ -7067,7 +7176,7 @@ function sleep(ms) {
|
|
|
7067
7176
|
setTimeout(resolve12, ms);
|
|
7068
7177
|
});
|
|
7069
7178
|
}
|
|
7070
|
-
var defaultSnapshotRetryDelaysMs, toolCallOutputTypes, toolCallItemTypes;
|
|
7179
|
+
var defaultSnapshotRetryDelaysMs, defaultOutboxMaxInFlightPushes, toolCallOutputTypes, toolCallItemTypes;
|
|
7071
7180
|
var init_integration = __esm({
|
|
7072
7181
|
"src/pipeline/integration.ts"() {
|
|
7073
7182
|
"use strict";
|
|
@@ -7081,6 +7190,7 @@ var init_integration = __esm({
|
|
|
7081
7190
|
init_threadEventLoop();
|
|
7082
7191
|
init_transition();
|
|
7083
7192
|
defaultSnapshotRetryDelaysMs = [1e3, 5e3];
|
|
7193
|
+
defaultOutboxMaxInFlightPushes = 16;
|
|
7084
7194
|
toolCallOutputTypes = /* @__PURE__ */ new Map([
|
|
7085
7195
|
["function_call", "function_call_output"],
|
|
7086
7196
|
["custom_tool_call", "custom_tool_call_output"]
|
|
@@ -8739,6 +8849,14 @@ function codexStartRequestTimeoutMs() {
|
|
|
8739
8849
|
const parsed = Number.parseInt(raw, 10);
|
|
8740
8850
|
return Number.isFinite(parsed) && parsed > 0 ? parsed : CODEX_START_REQUEST_TIMEOUT_MS;
|
|
8741
8851
|
}
|
|
8852
|
+
function outboxMaxInFlightPushesOverride() {
|
|
8853
|
+
const raw = process.env.LINZUMI_OUTBOX_MAX_INFLIGHT_PUSHES?.trim();
|
|
8854
|
+
if (raw === void 0 || raw === "") {
|
|
8855
|
+
return void 0;
|
|
8856
|
+
}
|
|
8857
|
+
const parsed = Number.parseInt(raw, 10);
|
|
8858
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : void 0;
|
|
8859
|
+
}
|
|
8742
8860
|
function isCodexStartRequestTimeoutError(error) {
|
|
8743
8861
|
return error instanceof CodexStartRequestTimeoutError;
|
|
8744
8862
|
}
|
|
@@ -8983,7 +9101,7 @@ function createChannelSessionPipeline(args, state, payloadContext) {
|
|
|
8983
9101
|
instanceId: args.instanceId,
|
|
8984
9102
|
threadKey,
|
|
8985
9103
|
persistDir: args.options.pipelinePersistDir,
|
|
8986
|
-
push: (event, payload) => pipelinePush(args, state, event, payload),
|
|
9104
|
+
push: (event, payload, _timeoutMs, onSent) => pipelinePush(args, state, event, payload, onSent),
|
|
8987
9105
|
wire: () => ({
|
|
8988
9106
|
workspaceSlug: session.workspaceSlug,
|
|
8989
9107
|
channelSlug: session.channelSlug,
|
|
@@ -9014,15 +9132,16 @@ function createChannelSessionPipeline(args, state, payloadContext) {
|
|
|
9014
9132
|
args.log(event, fields);
|
|
9015
9133
|
},
|
|
9016
9134
|
outboxRetryDelaysMs: args.options.pipelineOutboxRetryDelaysMs,
|
|
9135
|
+
outboxMaxInFlightPushes: outboxMaxInFlightPushesOverride(),
|
|
9017
9136
|
snapshotRetryDelaysMs: args.options.pipelineSnapshotRetryDelaysMs,
|
|
9018
9137
|
statsIntervalMs: args.options.pipelineStatsIntervalMs,
|
|
9019
9138
|
turnStalledThresholdMs: args.options.pipelineTurnStalledThresholdMs
|
|
9020
9139
|
});
|
|
9021
9140
|
}
|
|
9022
|
-
async function pipelinePush(args, state, event, payload) {
|
|
9141
|
+
async function pipelinePush(args, state, event, payload, onSent) {
|
|
9023
9142
|
const prepared = await preparePipelinePushPayload(args, event, payload);
|
|
9024
9143
|
try {
|
|
9025
|
-
return await pushOk2(args.kandan, args.topic, event, prepared);
|
|
9144
|
+
return await pushOk2(args.kandan, args.topic, event, prepared, onSent);
|
|
9026
9145
|
} catch (error) {
|
|
9027
9146
|
if (isConnectionLostPushError(error)) {
|
|
9028
9147
|
state.pipeline?.pause();
|
|
@@ -12060,8 +12179,8 @@ function developerInstructionsForThreadStart(options) {
|
|
|
12060
12179
|
})
|
|
12061
12180
|
};
|
|
12062
12181
|
}
|
|
12063
|
-
async function pushOk2(kandan, topic, event, payload) {
|
|
12064
|
-
const reply = await kandan.push(topic, event, payload);
|
|
12182
|
+
async function pushOk2(kandan, topic, event, payload, onSent) {
|
|
12183
|
+
const reply = await kandan.push(topic, event, payload, onSent);
|
|
12065
12184
|
if (isJsonObject(reply) && reply.status === "ok" && isJsonObject(reply.response)) {
|
|
12066
12185
|
return reply.response;
|
|
12067
12186
|
}
|
|
@@ -12393,10 +12512,10 @@ function createClaudeCodeSessionPipeline(host) {
|
|
|
12393
12512
|
let lastSourceSeq;
|
|
12394
12513
|
let lastUsage;
|
|
12395
12514
|
let pipeline2;
|
|
12396
|
-
const push = async (event, payload, timeoutMs) => {
|
|
12515
|
+
const push = async (event, payload, timeoutMs, onSent) => {
|
|
12397
12516
|
const prepared = host.preparePush === void 0 ? payload : await host.preparePush(event, payload);
|
|
12398
12517
|
try {
|
|
12399
|
-
return await host.push(event, prepared, timeoutMs);
|
|
12518
|
+
return await host.push(event, prepared, timeoutMs, onSent);
|
|
12400
12519
|
} catch (error) {
|
|
12401
12520
|
if (isConnectionLostPushError(error)) {
|
|
12402
12521
|
pipeline2.pause();
|
|
@@ -19829,7 +19948,7 @@ var linzumiCliVersion, linzumiCliVersionText;
|
|
|
19829
19948
|
var init_version = __esm({
|
|
19830
19949
|
"src/version.ts"() {
|
|
19831
19950
|
"use strict";
|
|
19832
|
-
linzumiCliVersion = "0.0.
|
|
19951
|
+
linzumiCliVersion = "0.0.103-beta";
|
|
19833
19952
|
linzumiCliVersionText = `linzumi ${linzumiCliVersion}`;
|
|
19834
19953
|
}
|
|
19835
19954
|
});
|
|
@@ -24848,9 +24967,7 @@ async function openLocalCodexRunner(options, log2, cleanup, close) {
|
|
|
24848
24967
|
rebuildArgs.codexThreadId
|
|
24849
24968
|
);
|
|
24850
24969
|
let rebuilt = false;
|
|
24851
|
-
const rebuildProviderBinding = threadModelProviderBindings.get(
|
|
24852
|
-
rebuildArgs.kandanThreadId
|
|
24853
|
-
) ?? // Belt-and-suspenders: if the persisted map missed this thread
|
|
24970
|
+
const rebuildProviderBinding = threadModelProviderBindings.get(rebuildArgs.kandanThreadId) ?? // Belt-and-suspenders: if the persisted map missed this thread
|
|
24854
24971
|
// but the in-scope establishing `control` still carries the
|
|
24855
24972
|
// provider (the server now re-injects it on reconnect_thread),
|
|
24856
24973
|
// forward that directly so the rebuild never strands a wafer turn.
|
|
@@ -24876,7 +24993,9 @@ async function openLocalCodexRunner(options, log2, cleanup, close) {
|
|
|
24876
24993
|
// (the in-scope `control` is a reconnect_thread that no longer
|
|
24877
24994
|
// carries it) so the respawned wafer/GLM worker can load the
|
|
24878
24995
|
// `linzumi` provider and resume instead of stranding the turn.
|
|
24879
|
-
...rebuildProviderBinding?.modelProvider === void 0 ? {} : {
|
|
24996
|
+
...rebuildProviderBinding?.modelProvider === void 0 ? {} : {
|
|
24997
|
+
modelProvider: rebuildProviderBinding.modelProvider
|
|
24998
|
+
},
|
|
24880
24999
|
...rebuildProviderBinding?.llmProxy === void 0 ? {} : { llmProxy: rebuildProviderBinding.llmProxy },
|
|
24881
25000
|
sourceSeq: message.seq,
|
|
24882
25001
|
workDescription: message.body,
|
|
@@ -28452,8 +28571,8 @@ async function startClaudeCodeProviderInstance(args) {
|
|
|
28452
28571
|
codexThreadId: activeSessionId ?? args.resumeSessionId,
|
|
28453
28572
|
rootSeq
|
|
28454
28573
|
}),
|
|
28455
|
-
push: async (event, payload) => {
|
|
28456
|
-
const reply = await args.kandan.push(args.topic, event, payload);
|
|
28574
|
+
push: async (event, payload, _timeoutMs, onSent) => {
|
|
28575
|
+
const reply = await args.kandan.push(args.topic, event, payload, onSent);
|
|
28457
28576
|
if (isJsonObject(reply) && reply.status === "ok") {
|
|
28458
28577
|
return reply;
|
|
28459
28578
|
}
|
package/package.json
CHANGED