@agentunion/fastaun 0.5.34 → 0.5.35
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 +30 -1
- package/_packed_docs/CHANGELOG.md +30 -1
- package/_packed_docs/INDEX.md +11 -11
- package/_packed_docs/KITE_DOCS_GUIDE.md +9 -9
- package/_packed_docs/agent.md/SCHEMA.md +1 -1
- package/_packed_docs/aun/346/265/213/350/257/225/350/277/220/350/241/214/346/214/207/345/215/227.md +2 -2
- package/_packed_docs/protocol/Ownership/345/215/217/350/256/256/345/256/232/344/271/2112.1.md +17 -17
- package/_packed_docs/protocol/echo-probe-gateway.md +99 -0
- package/_packed_docs/protocol/echo-probe-sdk.md +91 -0
- package/_packed_docs/sdk/0.5.35-SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +189 -0
- package/_packed_docs/sdk/0.5.35-SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +204 -0
- package/_packed_docs/sdk/04-/350/277/236/346/216/245/344/270/216/350/256/244/350/257/201.md +2 -2
- package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +32 -6
- package/_packed_docs/sdk/09-group-rpc-manual.md +7 -7
- package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +13 -13
- package/_packed_docs/sdk/AUN/344/272/213/344/273/266/345/217/221/345/270/203/350/256/242/351/230/205/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +73 -3
- package/_packed_docs/sdk/AUN/344/272/213/344/273/266/345/217/221/345/270/203/350/256/242/351/230/205/345/274/200/345/217/221/347/247/273/346/244/215/346/214/207/345/215/227.md +50 -8
- package/_packed_docs/sdk/INDEX.md +18 -18
- package/_packed_docs/sdk/Ownership-SDK/347/274/226/346/216/222/346/214/207/345/215/2272.1.md +1 -1
- package/_packed_docs/sdk/Ownership2.1-SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +5 -5
- package/_packed_docs/sdk/Ownership2.1-SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +5 -5
- package/_packed_docs/sdk/Ownership2.1/350/257/246/347/273/206/350/256/276/350/256/241.md +9 -9
- package/_packed_docs//346/266/210/346/201/257/345/274/271/346/200/247/350/241/245/346/213/211/351/200/232/351/201/223/345/256/236/346/226/275/350/256/241/345/210/222.md +400 -0
- package/_packed_docs//346/266/210/346/201/257/345/274/271/346/200/247/350/241/245/346/213/211/351/200/232/351/201/223/346/226/271/346/241/210.md +485 -0
- package/dist/auth.js +31 -43
- package/dist/auth.js.map +1 -1
- package/dist/client/delivery.d.ts +7 -1
- package/dist/client/delivery.js +137 -16
- package/dist/client/delivery.js.map +1 -1
- package/dist/client/lifecycle.js +10 -1
- package/dist/client/lifecycle.js.map +1 -1
- package/dist/client/rpc-pipeline.d.ts +2 -0
- package/dist/client/rpc-pipeline.js +65 -7
- package/dist/client/rpc-pipeline.js.map +1 -1
- package/dist/client/sync-channels.d.ts +2 -1
- package/dist/client/sync-channels.js +33 -14
- package/dist/client/sync-channels.js.map +1 -1
- package/dist/client/v2-e2ee.d.ts +1 -0
- package/dist/client/v2-e2ee.js +19 -5
- package/dist/client/v2-e2ee.js.map +1 -1
- package/dist/client.d.ts +15 -0
- package/dist/client.js +310 -49
- package/dist/client.js.map +1 -1
- package/dist/events.d.ts +1 -0
- package/dist/events.js +5 -0
- package/dist/events.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/mail-client.d.ts +101 -0
- package/dist/mail-client.js +369 -0
- package/dist/mail-client.js.map +1 -0
- package/dist/pubsub/binding.js +9 -2
- package/dist/pubsub/binding.js.map +1 -1
- package/dist/pubsub/channel.d.ts +11 -3
- package/dist/pubsub/channel.js +88 -7
- package/dist/pubsub/channel.js.map +1 -1
- package/dist/pubsub/client.d.ts +8 -2
- package/dist/pubsub/client.js +59 -17
- package/dist/pubsub/client.js.map +1 -1
- package/dist/pubsub/index.d.ts +2 -2
- package/dist/pubsub/index.js +1 -1
- package/dist/pubsub/index.js.map +1 -1
- package/dist/pubsub/service.d.ts +6 -0
- package/dist/pubsub/service.js +100 -9
- package/dist/pubsub/service.js.map +1 -1
- package/dist/pubsub/types.d.ts +11 -1
- package/dist/tools/cross-sdk-agent.d.ts +1 -1
- package/dist/transport.d.ts +4 -0
- package/dist/transport.js +39 -2
- package/dist/transport.js.map +1 -1
- package/dist/udp-standby.d.ts +89 -0
- package/dist/udp-standby.js +487 -0
- package/dist/udp-standby.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +5 -1
- package/scripts/patch-imapflow-external.mjs +69 -0
package/dist/client/delivery.js
CHANGED
|
@@ -104,9 +104,73 @@ function deduplicatePlainForwardPageMessages(value, afterSeq) {
|
|
|
104
104
|
}
|
|
105
105
|
export class MessageDeliveryEngine {
|
|
106
106
|
runtime;
|
|
107
|
+
forwardAckJobs = new Map();
|
|
108
|
+
forwardAckTasks = new Set();
|
|
109
|
+
scheduleForwardAck(ns, seq, send) {
|
|
110
|
+
const client = this.runtime.client;
|
|
111
|
+
if (client._closing || seq <= 0)
|
|
112
|
+
return;
|
|
113
|
+
const scope = () => [client._aid, client._deviceId, client._slotId, this.captureInlineAckGeneration(),
|
|
114
|
+
client._v2RuntimeGeneration, client._transport, client._transport?._connectionGeneration,
|
|
115
|
+
client._transport?._workerGeneration, this.captureSeqNamespaceGeneration(ns)];
|
|
116
|
+
const current = scope();
|
|
117
|
+
const previous = this.forwardAckJobs.get(ns);
|
|
118
|
+
if (previous && previous.scope.every((value, i) => value === current[i])) {
|
|
119
|
+
if (seq > previous.seq) {
|
|
120
|
+
previous.seq = seq;
|
|
121
|
+
previous.send = send;
|
|
122
|
+
}
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
const job = { seq, scope: current, send };
|
|
126
|
+
this.forwardAckJobs.set(ns, job);
|
|
127
|
+
const isCurrent = () => this.forwardAckJobs.get(ns) === job && job.scope.every((value, i) => value === scope()[i]);
|
|
128
|
+
const task = (async () => {
|
|
129
|
+
let failures = 0;
|
|
130
|
+
while (isCurrent()) {
|
|
131
|
+
const pending = job.seq;
|
|
132
|
+
try {
|
|
133
|
+
await job.send(pending);
|
|
134
|
+
failures = 0;
|
|
135
|
+
if (job.seq <= pending) {
|
|
136
|
+
if (this.forwardAckJobs.get(ns) === job)
|
|
137
|
+
this.forwardAckJobs.delete(ns);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
if (!isCurrent() || client._closing || client.state !== ConnectionState.READY)
|
|
143
|
+
return;
|
|
144
|
+
if (job.seq <= pending)
|
|
145
|
+
await new Promise(resolve => setTimeout(resolve, Math.min(100 * 2 ** Math.min(failures++, 5), 3000)));
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
})().finally(() => {
|
|
149
|
+
if (this.forwardAckJobs.get(ns) === job)
|
|
150
|
+
this.forwardAckJobs.delete(ns);
|
|
151
|
+
this.forwardAckTasks.delete(task);
|
|
152
|
+
});
|
|
153
|
+
this.forwardAckTasks.add(task);
|
|
154
|
+
}
|
|
155
|
+
drainForwardAcks() {
|
|
156
|
+
if (!this.forwardAckTasks.size)
|
|
157
|
+
return;
|
|
158
|
+
return this.waitForwardAcks();
|
|
159
|
+
}
|
|
160
|
+
async waitForwardAcks() {
|
|
161
|
+
let timer;
|
|
162
|
+
try {
|
|
163
|
+
await Promise.race([Promise.allSettled([...this.forwardAckTasks]), new Promise(resolve => { timer = setTimeout(resolve, 1000); })]);
|
|
164
|
+
}
|
|
165
|
+
finally {
|
|
166
|
+
if (timer)
|
|
167
|
+
clearTimeout(timer);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
107
170
|
realtimeTailHeads = null;
|
|
108
171
|
realtimeSyncing = null;
|
|
109
172
|
pendingGroupPullUpper = null;
|
|
173
|
+
pendingV2GroupPulls = new Set();
|
|
110
174
|
onlineUnreadHintTargets = null;
|
|
111
175
|
onlineUnreadHintTasks = null;
|
|
112
176
|
backgroundPullNeeds = new Map();
|
|
@@ -1106,7 +1170,7 @@ export class MessageDeliveryEngine {
|
|
|
1106
1170
|
this.onGroupV2AckSucceeded(groupId, actualAckSeq, generation);
|
|
1107
1171
|
}
|
|
1108
1172
|
}
|
|
1109
|
-
async commitPlainForwardPage(ns, afterSeq, method, result, groupId = '') {
|
|
1173
|
+
async commitPlainForwardPage(ns, afterSeq, method, result, groupId = '', background = false) {
|
|
1110
1174
|
if (!isJsonObject(result)) {
|
|
1111
1175
|
throw new Error(`${method} response must be an object`);
|
|
1112
1176
|
}
|
|
@@ -1250,7 +1314,10 @@ export class MessageDeliveryEngine {
|
|
|
1250
1314
|
throw new Error(`${ackMethod} cannot confirm pending Forward watermark ${pendingAckSeq}`);
|
|
1251
1315
|
}
|
|
1252
1316
|
this.ensurePullOperationCurrent(ns);
|
|
1253
|
-
|
|
1317
|
+
if (background)
|
|
1318
|
+
this.scheduleForwardAck(ns, pendingAckSeq, seq => this.confirmPlainForwardAck(ns, ackMethod, seq, groupId));
|
|
1319
|
+
else
|
|
1320
|
+
await this.confirmPlainForwardAck(ns, ackMethod, pendingAckSeq, groupId);
|
|
1254
1321
|
}
|
|
1255
1322
|
this.syncProgress(ns, {
|
|
1256
1323
|
rawCount: messages.length,
|
|
@@ -1458,6 +1525,7 @@ export class MessageDeliveryEngine {
|
|
|
1458
1525
|
this.pendingGroupInlineAckNamespaces = null;
|
|
1459
1526
|
this.realtimeSyncing = null;
|
|
1460
1527
|
this.pendingGroupPullUpper = null;
|
|
1528
|
+
this.pendingV2GroupPulls.clear();
|
|
1461
1529
|
this.onlineUnreadHintTargets = null;
|
|
1462
1530
|
this.onlineUnreadHintTasks = null;
|
|
1463
1531
|
this.realtimeTailHeads = null;
|
|
@@ -1937,6 +2005,11 @@ export class MessageDeliveryEngine {
|
|
|
1937
2005
|
this.backgroundPullNeeds.delete(ns);
|
|
1938
2006
|
continue;
|
|
1939
2007
|
}
|
|
2008
|
+
if (this.pendingV2GroupPulls.has(ns)) {
|
|
2009
|
+
if (!client._v2Session)
|
|
2010
|
+
continue;
|
|
2011
|
+
this.pendingV2GroupPulls.delete(ns);
|
|
2012
|
+
}
|
|
1940
2013
|
if (ns.startsWith('p2p:') && !this.hasP2pApplicationSubscription())
|
|
1941
2014
|
continue;
|
|
1942
2015
|
if (need.messageClassRequest && need.messageClassRequest.message_class !== 'sdk_control') {
|
|
@@ -2362,6 +2435,8 @@ export class MessageDeliveryEngine {
|
|
|
2362
2435
|
return applicationResult({ ...result, message_class: 'sdk_control' });
|
|
2363
2436
|
if (!APP_SEND_ENVELOPE_METHODS.has(method) || !isJsonObject(result))
|
|
2364
2437
|
return result;
|
|
2438
|
+
if (result.status === 'echo_return')
|
|
2439
|
+
return result;
|
|
2365
2440
|
let out = { ...result };
|
|
2366
2441
|
const serverEnvelope = method === 'group.send' && isJsonObject(out.envelope)
|
|
2367
2442
|
? { ...out.envelope }
|
|
@@ -2686,8 +2761,10 @@ export class MessageDeliveryEngine {
|
|
|
2686
2761
|
return this.runApplicationPage(namespace, source, async () => { await this.publishAppEvent(event, payload, source, deliveryContext); });
|
|
2687
2762
|
}
|
|
2688
2763
|
}
|
|
2689
|
-
if ((event === 'message.received' || event === 'group.message_created') && isJsonObject(payload)) {
|
|
2690
|
-
client._maybeAppendEchoTraceReceive(payload)
|
|
2764
|
+
if (source !== 'echo_return' && (event === 'message.received' || event === 'group.message_created') && isJsonObject(payload)) {
|
|
2765
|
+
if (client._maybeAppendEchoTraceReceive(payload)) {
|
|
2766
|
+
return client._returnReceivedEcho(payload);
|
|
2767
|
+
}
|
|
2691
2768
|
}
|
|
2692
2769
|
this.logAppMessagePublish(event, payload, source);
|
|
2693
2770
|
if (isJsonObject(payload)) {
|
|
@@ -2929,7 +3006,14 @@ export class MessageDeliveryEngine {
|
|
|
2929
3006
|
}
|
|
2930
3007
|
async onRawMessageReceived(data) {
|
|
2931
3008
|
const client = this.runtime.client;
|
|
2932
|
-
if (client.
|
|
3009
|
+
if (isJsonObject(data) && !client._echoStarts.has(data))
|
|
3010
|
+
client._echoStarts.set(data, performance.now());
|
|
3011
|
+
const message = isJsonObject(data) ? data : undefined;
|
|
3012
|
+
const payload = message?.payload;
|
|
3013
|
+
const plainEcho = message && !message.encrypted && !message.encrypt && isJsonObject(payload)
|
|
3014
|
+
&& !String(payload.type ?? '').trim().toLowerCase().startsWith('e2ee') && !payload.ciphertext
|
|
3015
|
+
&& !client._isEncryptedPushMessage(message) && client._isEchoPayload(payload);
|
|
3016
|
+
if (client._p2pPeerPullEnabled && !plainEcho) {
|
|
2933
3017
|
await this.onPeerPush(data);
|
|
2934
3018
|
return;
|
|
2935
3019
|
}
|
|
@@ -2998,6 +3082,7 @@ export class MessageDeliveryEngine {
|
|
|
2998
3082
|
return;
|
|
2999
3083
|
}
|
|
3000
3084
|
const msg = { ...data };
|
|
3085
|
+
client._echoStarts.set(msg, client._echoStarts.get(data) ?? performance.now());
|
|
3001
3086
|
if (!this.messageTargetsCurrentInstance(msg)) {
|
|
3002
3087
|
client._clientLog.debug(`P2P push filtered by instance: message_id=${String(msg.message_id ?? '')}, seq=${String(msg.seq ?? '')}, target_device=${String(msg.device_id ?? '')}, target_slot=${String(msg.slot_id ?? '')}, local_device=${client._deviceId}, local_slot=${client._slotId}`);
|
|
3003
3088
|
return;
|
|
@@ -3054,6 +3139,8 @@ export class MessageDeliveryEngine {
|
|
|
3054
3139
|
}
|
|
3055
3140
|
async onRawGroupMessageCreated(data) {
|
|
3056
3141
|
const client = this.runtime.client;
|
|
3142
|
+
if (isJsonObject(data) && !client._echoStarts.has(data))
|
|
3143
|
+
client._echoStarts.set(data, performance.now());
|
|
3057
3144
|
const tStart = Date.now();
|
|
3058
3145
|
if (isJsonObject(data)) {
|
|
3059
3146
|
client._logMessageDebug('server-push', '_raw.group.message_created', 'group.message_created', data);
|
|
@@ -3094,6 +3181,7 @@ export class MessageDeliveryEngine {
|
|
|
3094
3181
|
}
|
|
3095
3182
|
const msg = { ...data };
|
|
3096
3183
|
const groupId = String(msg.group_id ?? '');
|
|
3184
|
+
client._echoStarts.set(msg, client._echoStarts.get(data) ?? performance.now());
|
|
3097
3185
|
const seq = msg.seq;
|
|
3098
3186
|
const payload = msg.payload;
|
|
3099
3187
|
if (groupId) {
|
|
@@ -3210,7 +3298,7 @@ export class MessageDeliveryEngine {
|
|
|
3210
3298
|
try {
|
|
3211
3299
|
// Gap Fill 本身就是 Forward Pull,必须沿用协调器的完整事务:
|
|
3212
3300
|
// 原始页提交成功后由协调器负责 Piggyback/终端 ACK。
|
|
3213
|
-
const operation = () => client._pullV2(afterSeq, _INTERNAL_MESSAGE_FLOW_LIMITS.pullPageSize, { gateLocked: true });
|
|
3301
|
+
const operation = () => client._pullV2(afterSeq, _INTERNAL_MESSAGE_FLOW_LIMITS.pullPageSize, { gateLocked: true, background: true });
|
|
3214
3302
|
const messages = await this.runAutomaticPull(ns, operation, (attempt) => client._rpcPipeline
|
|
3215
3303
|
? client._rpcPipeline.runPullSerialized(client._rpcPipeline.pullGateKeyForCall('message.pull', { after_seq: afterSeq, limit: _INTERNAL_MESSAGE_FLOW_LIMITS.pullPageSize }), attempt, true)
|
|
3216
3304
|
: client._withBackgroundRpc(attempt));
|
|
@@ -3859,7 +3947,7 @@ export class MessageDeliveryEngine {
|
|
|
3859
3947
|
tailHead = this.syncState(ns).head;
|
|
3860
3948
|
return tailResult;
|
|
3861
3949
|
}
|
|
3862
|
-
const opts = { gateLocked: true };
|
|
3950
|
+
const opts = { gateLocked: true, background };
|
|
3863
3951
|
if (request.max_pages !== undefined)
|
|
3864
3952
|
opts.maxPages = request.max_pages;
|
|
3865
3953
|
const messages = await client._pullV2(after, pageLimit, opts);
|
|
@@ -3985,7 +4073,7 @@ export class MessageDeliveryEngine {
|
|
|
3985
4073
|
const client = this.runtime.client;
|
|
3986
4074
|
const request = { after_seq: this.syncState(ns).ack, limit: pageLimit, max_pages: 1 };
|
|
3987
4075
|
const invoke = async () => {
|
|
3988
|
-
const messages = await client._pullV2(Number(request.after_seq), pageLimit, { gateLocked: true, maxPages: 1 });
|
|
4076
|
+
const messages = await client._pullV2(Number(request.after_seq), pageLimit, { gateLocked: true, maxPages: 1, background });
|
|
3989
4077
|
return { messages, raw_count: messages.length };
|
|
3990
4078
|
};
|
|
3991
4079
|
if (!client._rpcPipeline)
|
|
@@ -4843,7 +4931,7 @@ export class MessageDeliveryEngine {
|
|
|
4843
4931
|
const coordinator = client._v2E2EE;
|
|
4844
4932
|
const pendingAckSeq = Number(coordinator.pendingForwardAck?.(ns, committedAck) ?? 0);
|
|
4845
4933
|
if (pendingAckSeq > 0) {
|
|
4846
|
-
|
|
4934
|
+
this.scheduleForwardAck(ns, pendingAckSeq, seq => coordinator.confirmForwardGroupAck(groupId, seq, String(data.group_aid ?? '').trim() || undefined, true));
|
|
4847
4935
|
}
|
|
4848
4936
|
else {
|
|
4849
4937
|
const pendingNs = this.resolvePendingGroupInlineAckNamespace(ns);
|
|
@@ -4904,8 +4992,6 @@ export class MessageDeliveryEngine {
|
|
|
4904
4992
|
const groupId = typeof d.group_id === 'string' ? d.group_id.trim() : '';
|
|
4905
4993
|
const rawSeq = d.seq;
|
|
4906
4994
|
const inlinePresent = hasNonEmptyInlineMessage(d.inline_message);
|
|
4907
|
-
if (!client._v2Session && !(expectedVersion === 'v1' && inlinePresent))
|
|
4908
|
-
return;
|
|
4909
4995
|
const seq = this.realtimeHeadSeq(rawSeq, inlinePresent);
|
|
4910
4996
|
if (!groupId) {
|
|
4911
4997
|
client._clientLog.debug(`_onRawGroupV2MessageCreated skipped: group=${groupId || '<empty>'}, seq=${String(d.seq ?? '')}`);
|
|
@@ -4918,6 +5004,15 @@ export class MessageDeliveryEngine {
|
|
|
4918
5004
|
return;
|
|
4919
5005
|
}
|
|
4920
5006
|
const eventKind = String(d.kind ?? '').trim();
|
|
5007
|
+
if (!client._v2Session && !(expectedVersion === 'v1' && inlinePresent)) {
|
|
5008
|
+
if (client._sessionOptions?.background_sync !== false) {
|
|
5009
|
+
const ns = `group:${groupId}`;
|
|
5010
|
+
this.recordBackgroundPullNeed(ns, seq, eventKind === 'group.online_unread_hint', true);
|
|
5011
|
+
if (this.backgroundPullNeeds.has(ns))
|
|
5012
|
+
this.pendingV2GroupPulls.add(ns);
|
|
5013
|
+
}
|
|
5014
|
+
return;
|
|
5015
|
+
}
|
|
4921
5016
|
if (eventKind === 'group.online_unread_hint') {
|
|
4922
5017
|
if (client._sessionOptions.background_sync === false)
|
|
4923
5018
|
return;
|
|
@@ -5052,18 +5147,44 @@ export class MessageDeliveryEngine {
|
|
|
5052
5147
|
this.refreshPendingPeers();
|
|
5053
5148
|
return;
|
|
5054
5149
|
}
|
|
5055
|
-
if (!client._aid || !client._v2Session)
|
|
5150
|
+
if (!client._aid || !client._v2Session || client._sessionOptions?.background_sync === false)
|
|
5056
5151
|
return;
|
|
5057
5152
|
const ns = `p2p:${client._aid}`;
|
|
5058
5153
|
const generation = this.captureInlineAckGeneration();
|
|
5059
|
-
const
|
|
5060
|
-
|
|
5154
|
+
const state = this.syncState(ns);
|
|
5155
|
+
const afterSeq = state.ack;
|
|
5156
|
+
const hintSeq = positiveSafeSequenceHint(data.seq);
|
|
5157
|
+
if (hintSeq > 0 && afterSeq >= Math.max(hintSeq, state.head, Number(client._seqTracker.getMaxSeenSeq?.(ns) ?? 0), Number(client._pendingP2pPullUpper?.get?.(ns) ?? 0))
|
|
5158
|
+
&& afterSeq >= state.tail - 1 && !client._pendingOrderedMsgs.get(ns)?.size) {
|
|
5159
|
+
const coordinator = client._v2E2EE;
|
|
5160
|
+
const pendingAckSeq = Number(coordinator.pendingForwardAck?.(ns, afterSeq) ?? 0);
|
|
5161
|
+
if (pendingAckSeq > 0) {
|
|
5162
|
+
this.scheduleForwardAck(ns, pendingAckSeq, seq => coordinator.confirmForwardP2PAck(seq));
|
|
5163
|
+
}
|
|
5164
|
+
else {
|
|
5165
|
+
const pending = this.pendingP2PInlineAcks?.get(ns);
|
|
5166
|
+
if (pending)
|
|
5167
|
+
this.retryPendingP2PInlineAck(ns, pending.seq, 'covered online hint', afterSeq);
|
|
5168
|
+
}
|
|
5169
|
+
return;
|
|
5170
|
+
}
|
|
5171
|
+
this.recordBackgroundPullNeed(ns, hintSeq, true, true);
|
|
5061
5172
|
const pullTrigger = this.backgroundPullNeeds.get(ns)?.trigger;
|
|
5173
|
+
const tasks = this.onlineUnreadHintTasks ?? new Map();
|
|
5174
|
+
this.onlineUnreadHintTasks = tasks;
|
|
5175
|
+
if (tasks.has(ns))
|
|
5176
|
+
return;
|
|
5062
5177
|
let failed = false;
|
|
5063
|
-
|
|
5178
|
+
const task = this.runP2PForwardRecovery(ns, _INTERNAL_MESSAGE_FLOW_LIMITS.pullPageSize, true).then(() => undefined).catch((exc) => {
|
|
5064
5179
|
failed = true;
|
|
5065
5180
|
client._clientLog.debug(`P2P online unread hint background Forward failed: ns=${ns} err=${formatDeliveryError(exc)}`);
|
|
5066
|
-
}).finally(() =>
|
|
5181
|
+
}).finally(() => {
|
|
5182
|
+
if (tasks.get(ns) === task)
|
|
5183
|
+
tasks.delete(ns);
|
|
5184
|
+
this.finishBackgroundPull(ns, generation, afterSeq, failed, pullTrigger);
|
|
5185
|
+
});
|
|
5186
|
+
tasks.set(ns, task);
|
|
5187
|
+
client._safeAsync(task);
|
|
5067
5188
|
}
|
|
5068
5189
|
async saveSeqTrackerState() {
|
|
5069
5190
|
const client = this.runtime.client;
|