@agentunion/fastaun 0.5.8 → 0.5.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/CHANGELOG.md +32 -0
- package/_packed_docs/CHANGELOG.md +32 -0
- package/_packed_docs/agent.md/examples//347/276/244/347/273/204-/345/274/200/345/217/221/345/233/242/351/230/237.md +21 -0
- package/dist/agent-md-schema.js +3 -0
- package/dist/agent-md-schema.js.map +1 -1
- package/dist/aid-store.js +1 -3
- package/dist/aid-store.js.map +1 -1
- package/dist/auth.d.ts +3 -1
- package/dist/auth.js +64 -13
- package/dist/auth.js.map +1 -1
- package/dist/client/delivery.d.ts +4 -0
- package/dist/client/delivery.js +121 -20
- package/dist/client/delivery.js.map +1 -1
- package/dist/client/group-state.js +2 -2
- package/dist/client/group-state.js.map +1 -1
- package/dist/client/lifecycle.js +20 -8
- package/dist/client/lifecycle.js.map +1 -1
- package/dist/client/rpc-pipeline.d.ts +8 -0
- package/dist/client/rpc-pipeline.js +150 -32
- package/dist/client/rpc-pipeline.js.map +1 -1
- package/dist/client/v2-e2ee.js +12 -4
- package/dist/client/v2-e2ee.js.map +1 -1
- package/dist/client.js +87 -11
- package/dist/client.js.map +1 -1
- package/dist/discovery.d.ts +1 -0
- package/dist/discovery.js +3 -0
- package/dist/discovery.js.map +1 -1
- package/dist/facades.js +7 -3
- package/dist/facades.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/dist/net.d.ts +3 -0
- package/dist/net.js +13 -0
- package/dist/net.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/_packed_docs//345/217/221/345/270/203/346/212/245/345/221/212-0.5.6.md +0 -260
package/dist/client/delivery.js
CHANGED
|
@@ -67,6 +67,8 @@ export class MessageDeliveryEngine {
|
|
|
67
67
|
realtimeTailHeads = null;
|
|
68
68
|
realtimeSyncing = null;
|
|
69
69
|
pendingGroupPullUpper = null;
|
|
70
|
+
onlineUnreadHintTargets = null;
|
|
71
|
+
onlineUnreadHintTasks = null;
|
|
70
72
|
pendingP2PInlineAcks = null;
|
|
71
73
|
pendingGroupInlineAcks = null;
|
|
72
74
|
pendingGroupInlineAckNamespaces = null;
|
|
@@ -76,6 +78,20 @@ export class MessageDeliveryEngine {
|
|
|
76
78
|
constructor(runtime) {
|
|
77
79
|
this.runtime = runtime;
|
|
78
80
|
}
|
|
81
|
+
isPullOperationCurrent() {
|
|
82
|
+
const client = this.runtime.client;
|
|
83
|
+
const generation = client._pullOperationGeneration;
|
|
84
|
+
if (generation === undefined)
|
|
85
|
+
return true;
|
|
86
|
+
const pipeline = client._rpcPipeline;
|
|
87
|
+
return typeof pipeline?.isPullGenerationCurrent === 'function'
|
|
88
|
+
? pipeline.isPullGenerationCurrent(generation)
|
|
89
|
+
: true;
|
|
90
|
+
}
|
|
91
|
+
ensurePullOperationCurrent() {
|
|
92
|
+
if (!this.isPullOperationCurrent())
|
|
93
|
+
throw new Error('pull invalidated');
|
|
94
|
+
}
|
|
79
95
|
forwardCoordinator() {
|
|
80
96
|
const coordinator = this.runtime.client._v2E2EE;
|
|
81
97
|
if (!coordinator
|
|
@@ -91,6 +107,7 @@ export class MessageDeliveryEngine {
|
|
|
91
107
|
}
|
|
92
108
|
async confirmPlainForwardAck(ns, method, ackSeq, groupId = '') {
|
|
93
109
|
const client = this.runtime.client;
|
|
110
|
+
this.ensurePullOperationCurrent();
|
|
94
111
|
const coordinator = this.forwardCoordinator();
|
|
95
112
|
const generation = this.captureInlineAckGeneration();
|
|
96
113
|
coordinator.recordForwardAck(ns, ackSeq);
|
|
@@ -109,6 +126,7 @@ export class MessageDeliveryEngine {
|
|
|
109
126
|
_rpc_background: true,
|
|
110
127
|
};
|
|
111
128
|
const result = await client._rpcPipeline.rawCall(method, params, { background: true });
|
|
129
|
+
this.ensurePullOperationCurrent();
|
|
112
130
|
const actualAckSeq = this.resolveForwardAckSeq(result, ackSeq);
|
|
113
131
|
if (actualAckSeq < ackSeq) {
|
|
114
132
|
throw new Error(`${method} server ACK watermark ${actualAckSeq} is below requested ${ackSeq}`);
|
|
@@ -126,6 +144,7 @@ export class MessageDeliveryEngine {
|
|
|
126
144
|
throw new Error(`${method} response must be an object`);
|
|
127
145
|
}
|
|
128
146
|
const client = this.runtime.client;
|
|
147
|
+
this.ensurePullOperationCurrent();
|
|
129
148
|
const response = result;
|
|
130
149
|
const messages = deduplicatePlainForwardPageMessages(response.messages, afterSeq);
|
|
131
150
|
const coordinator = this.forwardCoordinator();
|
|
@@ -156,25 +175,30 @@ export class MessageDeliveryEngine {
|
|
|
156
175
|
let committed = false;
|
|
157
176
|
try {
|
|
158
177
|
for (const rawMessage of messages) {
|
|
178
|
+
this.ensurePullOperationCurrent();
|
|
159
179
|
const seq = positiveSafeSequenceHint(rawMessage.seq);
|
|
160
180
|
if (method === 'message.pull') {
|
|
161
181
|
const appEvent = this.p2pAppEventForMessage(rawMessage);
|
|
162
182
|
if (await this.publishPulledMessage(appEvent.event, ns, seq, appEvent.payload, false)) {
|
|
163
183
|
publishedCount += 1;
|
|
164
184
|
}
|
|
185
|
+
this.ensurePullOperationCurrent();
|
|
165
186
|
continue;
|
|
166
187
|
}
|
|
167
188
|
const message = normalizeGroupMentionMode(rawMessage);
|
|
168
189
|
if (this.recallEventFromGroupMessage(message)) {
|
|
169
190
|
if (await this.publishGroupRecallTombstone(groupId, seq, message)) {
|
|
191
|
+
this.ensurePullOperationCurrent();
|
|
170
192
|
this.markPublishedSeq(ns, seq);
|
|
171
193
|
publishedCount += 1;
|
|
172
194
|
}
|
|
173
195
|
}
|
|
174
196
|
else if (await this.publishPulledMessage('group.message_created', ns, seq, message, false)) {
|
|
197
|
+
this.ensurePullOperationCurrent();
|
|
175
198
|
publishedCount += 1;
|
|
176
199
|
}
|
|
177
200
|
}
|
|
201
|
+
this.ensurePullOperationCurrent();
|
|
178
202
|
if (messages.length > 0)
|
|
179
203
|
client._seqTracker.onPullResult(ns, messages, afterSeq);
|
|
180
204
|
const commitTarget = Math.max(client._seqTracker.getContiguousSeq(ns), retentionFloor, visibilityFloor, deferredServerCursor);
|
|
@@ -182,18 +206,21 @@ export class MessageDeliveryEngine {
|
|
|
182
206
|
client._seqTracker.forceContiguousSeq(ns, commitTarget);
|
|
183
207
|
}
|
|
184
208
|
if (client._seqTracker.getContiguousSeq(ns) !== pageContigBefore) {
|
|
209
|
+
this.ensurePullOperationCurrent();
|
|
185
210
|
await this.drainOrderedMessages(ns, undefined, false, false);
|
|
211
|
+
this.ensurePullOperationCurrent();
|
|
186
212
|
await client._commitSeqTrackerState(ns);
|
|
187
213
|
}
|
|
188
214
|
committed = true;
|
|
189
215
|
}
|
|
190
216
|
catch (exc) {
|
|
191
|
-
if (!committed && typeof client._seqTracker.restoreNamespaceSnapshot === 'function') {
|
|
217
|
+
if (this.isPullOperationCurrent() && !committed && typeof client._seqTracker.restoreNamespaceSnapshot === 'function') {
|
|
192
218
|
client._seqTracker.restoreNamespaceSnapshot(ns, pageTrackerSnapshot);
|
|
193
219
|
this.dropSeqTrackerPending(ns);
|
|
194
220
|
}
|
|
195
221
|
throw exc;
|
|
196
222
|
}
|
|
223
|
+
this.ensurePullOperationCurrent();
|
|
197
224
|
const committedAck = client._seqTracker.getContiguousSeq(ns);
|
|
198
225
|
if (deferredServerCursor > 0 && committedAck >= deferredServerCursor) {
|
|
199
226
|
coordinator.clearForwardCursor(ns, committedAck);
|
|
@@ -224,17 +251,21 @@ export class MessageDeliveryEngine {
|
|
|
224
251
|
if (clampedAckSeq < pendingAckSeq) {
|
|
225
252
|
throw new Error(`${ackMethod} cannot confirm pending Forward watermark ${pendingAckSeq}`);
|
|
226
253
|
}
|
|
254
|
+
this.ensurePullOperationCurrent();
|
|
227
255
|
await this.confirmPlainForwardAck(ns, ackMethod, pendingAckSeq, groupId);
|
|
228
256
|
}
|
|
229
257
|
return { rawCount: messages.length, publishedCount };
|
|
230
258
|
}
|
|
231
259
|
resetInlineAckState() {
|
|
232
260
|
this.inlineAckGeneration += 1;
|
|
261
|
+
void this.runtime.client._rpcPipeline?.invalidatePulls?.();
|
|
233
262
|
this.pendingP2PInlineAcks = null;
|
|
234
263
|
this.pendingGroupInlineAcks = null;
|
|
235
264
|
this.pendingGroupInlineAckNamespaces = null;
|
|
236
265
|
this.realtimeSyncing = null;
|
|
237
266
|
this.pendingGroupPullUpper = null;
|
|
267
|
+
this.onlineUnreadHintTargets = null;
|
|
268
|
+
this.onlineUnreadHintTasks = null;
|
|
238
269
|
this.realtimeTailHeads = null;
|
|
239
270
|
}
|
|
240
271
|
inlineGenerationIsCurrent(generation) {
|
|
@@ -366,12 +397,15 @@ export class MessageDeliveryEngine {
|
|
|
366
397
|
}
|
|
367
398
|
async publishOrderedQueueItem(ns, event, seq, payload, source, pullResponse = false) {
|
|
368
399
|
const client = this.runtime.client;
|
|
400
|
+
this.ensurePullOperationCurrent();
|
|
369
401
|
if (event === 'group.changed' && this.isGroupEventNamespace(ns)) {
|
|
370
402
|
await this.publishOrderedGroupChanged(payload, source);
|
|
403
|
+
this.ensurePullOperationCurrent();
|
|
371
404
|
return;
|
|
372
405
|
}
|
|
373
406
|
if (event === 'message.recalled') {
|
|
374
407
|
await this.publishMessageRecallTombstone(seq, payload);
|
|
408
|
+
this.ensurePullOperationCurrent();
|
|
375
409
|
return;
|
|
376
410
|
}
|
|
377
411
|
if (pullResponse) {
|
|
@@ -384,6 +418,7 @@ export class MessageDeliveryEngine {
|
|
|
384
418
|
if (isPromiseLike(published))
|
|
385
419
|
await published;
|
|
386
420
|
}
|
|
421
|
+
this.ensurePullOperationCurrent();
|
|
387
422
|
}
|
|
388
423
|
async publishOrderedGroupChanged(payload, source = 'ordered') {
|
|
389
424
|
const client = this.runtime.client;
|
|
@@ -1938,6 +1973,18 @@ export class MessageDeliveryEngine {
|
|
|
1938
1973
|
raw = response.effective_ack_seq;
|
|
1939
1974
|
else if (Object.prototype.hasOwnProperty.call(response, 'ack_seq'))
|
|
1940
1975
|
raw = response.ack_seq;
|
|
1976
|
+
else if (Object.prototype.hasOwnProperty.call(response, 'cursor')) {
|
|
1977
|
+
const cursor = response.cursor;
|
|
1978
|
+
const cursorObject = isJsonObject(cursor) ? cursor : null;
|
|
1979
|
+
if (cursorObject) {
|
|
1980
|
+
if (!Object.prototype.hasOwnProperty.call(cursorObject, 'current_seq'))
|
|
1981
|
+
return 0;
|
|
1982
|
+
raw = cursorObject.current_seq;
|
|
1983
|
+
}
|
|
1984
|
+
else {
|
|
1985
|
+
raw = cursor;
|
|
1986
|
+
}
|
|
1987
|
+
}
|
|
1941
1988
|
else
|
|
1942
1989
|
return requestedSeq;
|
|
1943
1990
|
return typeof raw === 'number' && Number.isSafeInteger(raw) && raw >= 0 ? raw : 0;
|
|
@@ -2020,19 +2067,20 @@ export class MessageDeliveryEngine {
|
|
|
2020
2067
|
const state = this.syncState(ns);
|
|
2021
2068
|
const needsForward = state.ack < state.tail - 1;
|
|
2022
2069
|
const backgroundEnabled = client._sessionOptions?.background_sync !== false;
|
|
2023
|
-
// Tail 期间到达的新 Push 可能只更新 maxSeen 而没有扩展 Tail
|
|
2024
|
-
|
|
2025
|
-
const tailMissedDuringPull = tailHead !== null
|
|
2026
|
-
&& Number(client._seqTracker.getMaxSeenSeq?.(ns) ?? 0) > state.head;
|
|
2070
|
+
// Tail 期间到达的新 Push 可能只更新 maxSeen 而没有扩展 Tail 窗口。
|
|
2071
|
+
const maxSeen = Number(client._seqTracker.getMaxSeenSeq?.(ns) ?? 0);
|
|
2072
|
+
const tailMissedDuringPull = tailHead !== null && maxSeen > state.head;
|
|
2027
2073
|
const tailForward = tailHead !== null && (needsForward || tailMissedDuringPull);
|
|
2028
2074
|
const backgroundWindowForward = (order.length === 1 && order[0] === 'forward' && !headForward)
|
|
2029
2075
|
|| (order.length === 1 && order[0] === 'tail' && tailHead === null && needsForward);
|
|
2030
2076
|
const foregroundForward = headForward || tailForward;
|
|
2031
2077
|
if (foregroundForward || backgroundEnabled && backgroundWindowForward) {
|
|
2078
|
+
const forwardTarget = Math.max(headForward ? pushSeq : 0, tailForward || backgroundWindowForward ? state.tail - 1 : 0, tailMissedDuringPull ? maxSeen : 0);
|
|
2079
|
+
const requiredPages = Math.max(1, Math.ceil(Math.max(0, forwardTarget - state.ack) / pageLimit));
|
|
2032
2080
|
result = await run({
|
|
2033
2081
|
after_seq: state.ack,
|
|
2034
2082
|
limit: pageLimit,
|
|
2035
|
-
...(headForward ? { max_pages: 2 } : order[0] === 'tail' ? { max_pages:
|
|
2083
|
+
...(headForward ? { max_pages: Math.max(2, requiredPages) } : order[0] === 'tail' ? { max_pages: requiredPages } : {}),
|
|
2036
2084
|
}, !foregroundForward, headForward || tailMissedDuringPull);
|
|
2037
2085
|
}
|
|
2038
2086
|
if (tailHead !== null && this.syncState(ns).ack < this.syncState(ns).tail - 1) {
|
|
@@ -2094,18 +2142,19 @@ export class MessageDeliveryEngine {
|
|
|
2094
2142
|
const state = this.syncState(ns);
|
|
2095
2143
|
const needsForward = state.ack < state.tail - 1;
|
|
2096
2144
|
const backgroundEnabled = client._sessionOptions?.background_sync !== false;
|
|
2097
|
-
|
|
2098
|
-
const tailMissedDuringPull = tailHead !== null
|
|
2099
|
-
&& Number(client._seqTracker.getMaxSeenSeq?.(ns) ?? 0) > state.head;
|
|
2145
|
+
const maxSeen = Number(client._seqTracker.getMaxSeenSeq?.(ns) ?? 0);
|
|
2146
|
+
const tailMissedDuringPull = tailHead !== null && maxSeen > state.head;
|
|
2100
2147
|
const tailForward = tailHead !== null && (needsForward || tailMissedDuringPull);
|
|
2101
2148
|
const backgroundWindowForward = (order.length === 1 && order[0] === 'forward' && !headForward)
|
|
2102
2149
|
|| (order.length === 1 && order[0] === 'tail' && tailHead === null && needsForward);
|
|
2103
2150
|
const foregroundForward = headForward || tailForward;
|
|
2104
2151
|
if (foregroundForward || backgroundEnabled && backgroundWindowForward) {
|
|
2152
|
+
const forwardTarget = Math.max(headForward ? pushSeq : 0, tailForward || backgroundWindowForward ? state.tail - 1 : 0, tailMissedDuringPull ? maxSeen : 0);
|
|
2153
|
+
const requiredPages = Math.max(1, Math.ceil(Math.max(0, forwardTarget - state.ack) / pageLimit));
|
|
2105
2154
|
result = await run({
|
|
2106
2155
|
after_seq: state.ack,
|
|
2107
2156
|
limit: pageLimit,
|
|
2108
|
-
...(headForward ? { max_pages: 2 } : order[0] === 'tail' ? { max_pages:
|
|
2157
|
+
...(headForward ? { max_pages: Math.max(2, requiredPages) } : order[0] === 'tail' ? { max_pages: requiredPages } : {}),
|
|
2109
2158
|
}, !foregroundForward, headForward || tailMissedDuringPull);
|
|
2110
2159
|
}
|
|
2111
2160
|
if (tailHead !== null && this.syncState(ns).ack < this.syncState(ns).tail - 1) {
|
|
@@ -2129,12 +2178,14 @@ export class MessageDeliveryEngine {
|
|
|
2129
2178
|
const key = client._rpcPipeline.pullGateKeyForCall('message.pull', request);
|
|
2130
2179
|
return await client._rpcPipeline.runPullSerialized(key, invoke, background);
|
|
2131
2180
|
}
|
|
2132
|
-
async runGroupForwardRecovery(groupId, ns, pageLimit, background = false) {
|
|
2181
|
+
async runGroupForwardRecovery(groupId, ns, pageLimit, background = false, throughSeq = 0) {
|
|
2133
2182
|
const client = this.runtime.client;
|
|
2134
|
-
const
|
|
2183
|
+
const ack = this.syncState(ns).ack;
|
|
2184
|
+
const maxPages = Math.max(1, Math.ceil(Math.max(0, throughSeq - ack) / pageLimit));
|
|
2185
|
+
const request = { group_id: groupId, after_seq: ack, limit: pageLimit, max_pages: maxPages };
|
|
2135
2186
|
const invoke = async () => {
|
|
2136
2187
|
const after = this.syncState(ns).ack;
|
|
2137
|
-
const messages = await client._pullGroupV2(groupId, after, pageLimit, { gateLocked: true, maxPages
|
|
2188
|
+
const messages = await client._pullGroupV2(groupId, after, pageLimit, { gateLocked: true, maxPages });
|
|
2138
2189
|
return { messages, raw_count: messages.length };
|
|
2139
2190
|
};
|
|
2140
2191
|
if (!client._rpcPipeline)
|
|
@@ -2770,9 +2821,34 @@ export class MessageDeliveryEngine {
|
|
|
2770
2821
|
if (!groupId)
|
|
2771
2822
|
return;
|
|
2772
2823
|
const ns = `group:${groupId}`;
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2824
|
+
const targets = this.onlineUnreadHintTargets ?? new Map();
|
|
2825
|
+
const tasks = this.onlineUnreadHintTasks ?? new Map();
|
|
2826
|
+
this.onlineUnreadHintTargets = targets;
|
|
2827
|
+
this.onlineUnreadHintTasks = tasks;
|
|
2828
|
+
targets.set(ns, Math.max(targets.get(ns) ?? 0, positiveSafeSequenceHint(data.seq)));
|
|
2829
|
+
if (tasks.has(ns))
|
|
2830
|
+
return;
|
|
2831
|
+
const task = Promise.resolve().then(async () => {
|
|
2832
|
+
try {
|
|
2833
|
+
while (true) {
|
|
2834
|
+
const ackBefore = this.syncState(ns).ack;
|
|
2835
|
+
await this.runGroupForwardRecovery(groupId, ns, 50, true, targets.get(ns) ?? 0);
|
|
2836
|
+
const ackAfter = this.syncState(ns).ack;
|
|
2837
|
+
if (ackAfter >= (targets.get(ns) ?? 0) || ackAfter <= ackBefore)
|
|
2838
|
+
return;
|
|
2839
|
+
}
|
|
2840
|
+
}
|
|
2841
|
+
catch (exc) {
|
|
2842
|
+
client._clientLog.debug(`online unread hint background Forward failed: ns=${ns} err=${formatDeliveryError(exc)}`);
|
|
2843
|
+
}
|
|
2844
|
+
finally {
|
|
2845
|
+
targets.delete(ns);
|
|
2846
|
+
if (tasks.get(ns) === task)
|
|
2847
|
+
tasks.delete(ns);
|
|
2848
|
+
}
|
|
2849
|
+
});
|
|
2850
|
+
tasks.set(ns, task);
|
|
2851
|
+
client._safeAsync(task);
|
|
2776
2852
|
}
|
|
2777
2853
|
async onRawGroupV2MessageCreated(data, expectedVersion, inlineGeneration) {
|
|
2778
2854
|
const client = this.runtime.client;
|
|
@@ -3250,11 +3326,13 @@ export class MessageDeliveryEngine {
|
|
|
3250
3326
|
}
|
|
3251
3327
|
async drainOrderedMessages(ns, beforeSeq, pullResponse = false, persist = true) {
|
|
3252
3328
|
const client = this.runtime.client;
|
|
3329
|
+
this.ensurePullOperationCurrent();
|
|
3253
3330
|
const queue = client._pendingOrderedMsgs.get(ns);
|
|
3254
3331
|
if (!queue || queue.size === 0)
|
|
3255
3332
|
return;
|
|
3256
3333
|
let delivered = false;
|
|
3257
3334
|
while (true) {
|
|
3335
|
+
this.ensurePullOperationCurrent();
|
|
3258
3336
|
const contig = client._seqTracker.getContiguousSeq(ns);
|
|
3259
3337
|
const ready = [...queue.keys()]
|
|
3260
3338
|
.filter((seq) => seq <= contig && (beforeSeq === undefined || seq < beforeSeq))
|
|
@@ -3280,6 +3358,7 @@ export class MessageDeliveryEngine {
|
|
|
3280
3358
|
continue;
|
|
3281
3359
|
}
|
|
3282
3360
|
await this.publishOrderedQueueItem(ns, item.event, seq, item.payload, 'ordered-drain', pullResponse);
|
|
3361
|
+
this.ensurePullOperationCurrent();
|
|
3283
3362
|
this.markPublishedSeq(ns, seq);
|
|
3284
3363
|
client._markOrderedSeqDelivered(ns, seq);
|
|
3285
3364
|
delivered = true;
|
|
@@ -3287,16 +3366,20 @@ export class MessageDeliveryEngine {
|
|
|
3287
3366
|
}
|
|
3288
3367
|
if (queue.size === 0) {
|
|
3289
3368
|
client._pendingOrderedMsgs.delete(ns);
|
|
3290
|
-
if (delivered && persist)
|
|
3369
|
+
if (delivered && persist) {
|
|
3370
|
+
this.ensurePullOperationCurrent();
|
|
3291
3371
|
await this.saveSeqTrackerState();
|
|
3372
|
+
}
|
|
3292
3373
|
}
|
|
3293
3374
|
}
|
|
3294
3375
|
async publishOrderedMessage(event, ns, seq, payload) {
|
|
3295
3376
|
const client = this.runtime.client;
|
|
3377
|
+
this.ensurePullOperationCurrent();
|
|
3296
3378
|
const seqNum = Number(seq);
|
|
3297
3379
|
if (!Number.isFinite(seqNum) || !Number.isInteger(seqNum) || seqNum <= 0) {
|
|
3298
3380
|
client._clientLog.debug(`publish ordered direct(no-seq): event=${event}, ns=${ns || '<none>'}, seq=${String(seq)}`);
|
|
3299
3381
|
await this.publishOrderedQueueItem(ns, event, seqNum, payload, 'ordered');
|
|
3382
|
+
this.ensurePullOperationCurrent();
|
|
3300
3383
|
return true;
|
|
3301
3384
|
}
|
|
3302
3385
|
if (client._pushedSeqs.get(ns)?.has(seqNum)) {
|
|
@@ -3314,6 +3397,7 @@ export class MessageDeliveryEngine {
|
|
|
3314
3397
|
return false;
|
|
3315
3398
|
}
|
|
3316
3399
|
await this.drainOrderedMessages(ns, seqNum);
|
|
3400
|
+
this.ensurePullOperationCurrent();
|
|
3317
3401
|
if (client._pushedSeqs.get(ns)?.has(seqNum)) {
|
|
3318
3402
|
client._clientLog.debug(`publish ordered skipped after-drain duplicate: event=${event}, ns=${ns}, seq=${seqNum}`);
|
|
3319
3403
|
return false;
|
|
@@ -3323,19 +3407,24 @@ export class MessageDeliveryEngine {
|
|
|
3323
3407
|
if (queue && queue.size === 0)
|
|
3324
3408
|
client._pendingOrderedMsgs.delete(ns);
|
|
3325
3409
|
await this.publishOrderedQueueItem(ns, event, seqNum, payload, 'ordered');
|
|
3410
|
+
this.ensurePullOperationCurrent();
|
|
3326
3411
|
this.markPublishedSeq(ns, seqNum);
|
|
3327
3412
|
client._markOrderedSeqDelivered(ns, seqNum);
|
|
3328
3413
|
client._clientLog.debug(`publish ordered delivered: event=${event}, ns=${ns}, seq=${seqNum}`);
|
|
3329
3414
|
await this.drainOrderedMessages(ns);
|
|
3330
|
-
if (!client._pendingOrderedMsgs.get(ns))
|
|
3415
|
+
if (!client._pendingOrderedMsgs.get(ns)) {
|
|
3416
|
+
this.ensurePullOperationCurrent();
|
|
3331
3417
|
await this.saveSeqTrackerState();
|
|
3418
|
+
}
|
|
3332
3419
|
return true;
|
|
3333
3420
|
}
|
|
3334
3421
|
async publishOrderedGroupRecall(ns, seq, message) {
|
|
3335
3422
|
const client = this.runtime.client;
|
|
3423
|
+
this.ensurePullOperationCurrent();
|
|
3336
3424
|
const seqNum = Number(seq);
|
|
3337
3425
|
if (!Number.isFinite(seqNum) || !Number.isInteger(seqNum) || seqNum <= 0) {
|
|
3338
3426
|
await this.publishGroupRecallTombstone(ns.replace(/^group:/, ''), seq, message);
|
|
3427
|
+
this.ensurePullOperationCurrent();
|
|
3339
3428
|
return true;
|
|
3340
3429
|
}
|
|
3341
3430
|
// 撤回 tombstone 也占 seq:推进 contiguous 并标记已发布,确保 ack 正常推进、不留空洞。
|
|
@@ -3345,24 +3434,31 @@ export class MessageDeliveryEngine {
|
|
|
3345
3434
|
}
|
|
3346
3435
|
client._seqTracker.onMessageSeq(ns, seqNum);
|
|
3347
3436
|
await this.publishGroupRecallTombstone(ns.replace(/^group:/, ''), seq, message);
|
|
3437
|
+
this.ensurePullOperationCurrent();
|
|
3348
3438
|
this.markPublishedSeq(ns, seqNum);
|
|
3349
3439
|
client._markOrderedSeqDelivered?.(ns, seqNum);
|
|
3350
3440
|
await this.drainOrderedMessages(ns);
|
|
3351
|
-
if (!client._pendingOrderedMsgs.get(ns))
|
|
3441
|
+
if (!client._pendingOrderedMsgs.get(ns)) {
|
|
3442
|
+
this.ensurePullOperationCurrent();
|
|
3352
3443
|
await this.saveSeqTrackerState();
|
|
3444
|
+
}
|
|
3353
3445
|
return true;
|
|
3354
3446
|
}
|
|
3355
3447
|
async publishPulledMessage(event, ns, seq, payload, persist = true) {
|
|
3356
3448
|
const client = this.runtime.client;
|
|
3449
|
+
this.ensurePullOperationCurrent();
|
|
3357
3450
|
const seqNum = Number(seq);
|
|
3358
3451
|
if (!Number.isFinite(seqNum) || !Number.isInteger(seqNum) || seqNum <= 0 || !ns) {
|
|
3359
3452
|
client._clientLog.debug(`publish pulled direct(no-seq): event=${event}, ns=${ns || '<none>'}, seq=${String(seq)}`);
|
|
3360
3453
|
if (event === 'message.recalled') {
|
|
3361
|
-
|
|
3454
|
+
const published = await this.publishMessageRecallTombstone(seq, payload);
|
|
3455
|
+
this.ensurePullOperationCurrent();
|
|
3456
|
+
return published;
|
|
3362
3457
|
}
|
|
3363
3458
|
const published = client._withPullResponseProcessing(ns, () => client._publishAppEvent(event, payload, 'pull'));
|
|
3364
3459
|
if (isPromiseLike(published))
|
|
3365
3460
|
await published;
|
|
3461
|
+
this.ensurePullOperationCurrent();
|
|
3366
3462
|
return true;
|
|
3367
3463
|
}
|
|
3368
3464
|
const queue = client._pendingOrderedMsgs.get(ns);
|
|
@@ -3374,22 +3470,27 @@ export class MessageDeliveryEngine {
|
|
|
3374
3470
|
return false;
|
|
3375
3471
|
}
|
|
3376
3472
|
await this.drainOrderedMessages(ns, seqNum, true, persist);
|
|
3473
|
+
this.ensurePullOperationCurrent();
|
|
3377
3474
|
queue?.delete(seqNum);
|
|
3378
3475
|
if (queue && queue.size === 0)
|
|
3379
3476
|
client._pendingOrderedMsgs.delete(ns);
|
|
3380
3477
|
if (event === 'message.recalled') {
|
|
3381
3478
|
const recallPublished = await this.publishMessageRecallTombstone(seqNum, payload);
|
|
3479
|
+
this.ensurePullOperationCurrent();
|
|
3382
3480
|
this.markPublishedSeq(ns, seqNum);
|
|
3383
3481
|
client._clientLog.debug(`publish pulled delivered: event=${event}, ns=${ns}, seq=${seqNum}`);
|
|
3384
3482
|
await this.drainOrderedMessages(ns, undefined, true, persist);
|
|
3483
|
+
this.ensurePullOperationCurrent();
|
|
3385
3484
|
return recallPublished;
|
|
3386
3485
|
}
|
|
3387
3486
|
const published = client._withPullResponseProcessing(ns, () => client._publishAppEvent(event, payload, 'pull'));
|
|
3388
3487
|
if (isPromiseLike(published))
|
|
3389
3488
|
await published;
|
|
3489
|
+
this.ensurePullOperationCurrent();
|
|
3390
3490
|
this.markPublishedSeq(ns, seqNum);
|
|
3391
3491
|
client._clientLog.debug(`publish pulled delivered: event=${event}, ns=${ns}, seq=${seqNum}`);
|
|
3392
3492
|
await this.drainOrderedMessages(ns, undefined, true, persist);
|
|
3493
|
+
this.ensurePullOperationCurrent();
|
|
3393
3494
|
return true;
|
|
3394
3495
|
}
|
|
3395
3496
|
}
|