@agentunion/fastaun 0.5.20 → 0.5.21
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 +47 -0
- package/_packed_docs/CHANGELOG.md +47 -0
- package/_packed_docs/INDEX.md +453 -440
- package/_packed_docs/KITE_DOCS_GUIDE.md +164 -161
- package/_packed_docs/agent.md/working/AID/347/261/273/345/236/213-owner/345/205/263/347/263/273/344/270/216/346/215/242owner/347/274/226/346/216/222/346/226/271/346/241/210.md +530 -0
- package/_packed_docs/agent.md/working/AID/347/261/273/345/236/213-owner/345/205/263/347/263/273/345/256/214/346/225/264/350/256/276/350/256/241/344/270/216/345/256/236/346/226/275/350/256/241/345/210/222.md +685 -0
- package/_packed_docs/agent.md/working/agent.md-schema/344/270/216/347/255/276/345/217/221/351/252/214/347/255/276/346/265/201/347/250/213/346/276/204/346/270/205.md +349 -0
- package/_packed_docs/agent.md/working//346/234/254/345/234/260Docker/346/265/213/350/257/225Bug/346/270/205/345/215/225.md +40 -0
- package/_packed_docs/protocol/06-/346/234/215/345/212/241/345/215/217/350/256/256.md +1433 -1392
- package/_packed_docs/protocol/08-AUN-E2EE.md +17 -12
- package/_packed_docs/protocol/Ownership/345/215/217/350/256/256/345/256/232/344/271/211.md +2 -0
- package/_packed_docs/protocol/Ownership/345/215/217/350/256/256/345/256/232/344/271/2112.1.md +666 -658
- package/_packed_docs/sdk/0.5.21-SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +368 -0
- package/_packed_docs/sdk/0.5.21-SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +350 -0
- package/_packed_docs/sdk/01-/345/277/253/351/200/237/345/274/200/345/247/213.md +1 -1
- package/_packed_docs/sdk/02-WebSocket/345/215/217/350/256/256.md +5 -1
- package/_packed_docs/sdk/03-/346/240/270/345/277/203/346/246/202/345/277/265.md +64 -64
- package/_packed_docs/sdk/04-/350/277/236/346/216/245/344/270/216/350/256/244/350/257/201.md +4 -1
- package/_packed_docs/sdk/05-E2EE/345/212/240/345/257/206/351/200/232/344/277/241.md +42 -39
- package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +147 -14
- package/_packed_docs/sdk/08-/346/234/200/344/275/263/345/256/236/350/267/265.md +48 -47
- package/_packed_docs/sdk/09-group-rpc-manual.md +5 -2
- package/_packed_docs/sdk/09-message-rpc-manual.md +250 -160
- package/_packed_docs/sdk/09-/345/207/255/350/257/201/346/234/215/345/212/241RPC/346/211/213/345/206/214.md +71 -0
- package/_packed_docs/sdk/09-/347/273/204/347/273/207/346/234/215/345/212/241RPC/346/211/213/345/206/214.md +88 -0
- package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +134 -130
- package/_packed_docs/sdk/INDEX.md +239 -221
- package/_packed_docs/sdk/Ownership-SDK/347/274/226/346/216/222/346/214/207/345/215/2272.1.md +930 -922
- 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 +106 -43
- 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 +180 -9
- package/_packed_docs/sdk/Ownership2.1-TDD/345/210/206/351/230/266/346/256/265/345/256/236/346/226/275/350/256/241/345/210/222.md +708 -708
- package/_packed_docs/sdk/Ownership2.1/350/257/246/347/273/206/350/256/276/350/256/241.md +480 -476
- package/_packed_docs/sdk//345/207/255/350/257/201/344/270/216/347/273/204/347/273/207/346/234/215/345/212/241SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +1 -1
- package/_packed_docs/sdk//345/207/255/350/257/201/344/270/216/347/273/204/347/273/207/346/234/215/345/212/241SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +2 -2
- package/dist/agent-md-schema.js +6 -4
- package/dist/agent-md-schema.js.map +1 -1
- package/dist/agent-md.d.ts +22 -2
- package/dist/agent-md.js +84 -67
- package/dist/agent-md.js.map +1 -1
- package/dist/aid-store.d.ts +13 -0
- package/dist/aid-store.js +50 -15
- package/dist/aid-store.js.map +1 -1
- package/dist/auth.js +4 -0
- package/dist/auth.js.map +1 -1
- package/dist/cert-utils.d.ts +1 -0
- package/dist/cert-utils.js +13 -0
- package/dist/cert-utils.js.map +1 -1
- package/dist/client/delivery.d.ts +59 -1
- package/dist/client/delivery.js +1018 -125
- package/dist/client/delivery.js.map +1 -1
- package/dist/client/rpc-pipeline.d.ts +4 -1
- package/dist/client/rpc-pipeline.js +123 -37
- package/dist/client/rpc-pipeline.js.map +1 -1
- package/dist/client/v2-e2ee.d.ts +12 -2
- package/dist/client/v2-e2ee.js +751 -294
- package/dist/client/v2-e2ee.js.map +1 -1
- package/dist/client.d.ts +26 -2
- package/dist/client.js +379 -63
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +4 -0
- package/dist/config.js +1 -0
- package/dist/config.js.map +1 -1
- package/dist/events.d.ts +18 -1
- package/dist/events.js +148 -9
- package/dist/events.js.map +1 -1
- package/dist/facades.d.ts +43 -1
- package/dist/facades.js +363 -7
- package/dist/facades.js.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/keystore/aid-db.d.ts +6 -1
- package/dist/keystore/aid-db.js +184 -42
- package/dist/keystore/aid-db.js.map +1 -1
- package/dist/keystore/index.d.ts +14 -0
- package/dist/keystore/local-token-store.d.ts +9 -1
- package/dist/keystore/local-token-store.js +79 -14
- package/dist/keystore/local-token-store.js.map +1 -1
- package/dist/org-protocol.d.ts +45 -0
- package/dist/org-protocol.js +754 -11
- package/dist/org-protocol.js.map +1 -1
- package/dist/ownership-v21.d.ts +16 -3
- package/dist/ownership-v21.js +35 -17
- package/dist/ownership-v21.js.map +1 -1
- package/dist/ownership-workflow.d.ts +17 -0
- package/dist/ownership-workflow.js +511 -26
- package/dist/ownership-workflow.js.map +1 -1
- package/dist/secret-store/file-store.js +84 -0
- package/dist/secret-store/file-store.js.map +1 -1
- package/dist/seq-tracker.d.ts +1 -0
- package/dist/seq-tracker.js +2 -2
- package/dist/seq-tracker.js.map +1 -1
- package/dist/tools/cross-sdk-agent.d.ts +66 -3
- package/dist/tools/cross-sdk-agent.js +466 -36
- package/dist/tools/cross-sdk-agent.js.map +1 -1
- package/dist/transport.d.ts +3 -0
- package/dist/transport.js +98 -44
- package/dist/transport.js.map +1 -1
- package/dist/types.d.ts +1 -0
- package/dist/v2/e2ee/encrypt-group.js +1 -0
- package/dist/v2/e2ee/encrypt-group.js.map +1 -1
- package/dist/v2/e2ee/encrypt-p2p.js +1 -0
- package/dist/v2/e2ee/encrypt-p2p.js.map +1 -1
- package/dist/v2/e2ee/types.d.ts +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
|
@@ -13,6 +13,8 @@ export declare class RpcPipeline {
|
|
|
13
13
|
private pullDrainedCheckQueued;
|
|
14
14
|
constructor(runtime: ClientRuntime);
|
|
15
15
|
call(method: string, params?: RpcParams): Promise<RpcResult>;
|
|
16
|
+
private _callWithSent;
|
|
17
|
+
private _call;
|
|
16
18
|
preflight(method: string, params?: RpcParams): RpcPreflightResult;
|
|
17
19
|
mergeInstanceProtectedHeaders(method: string, params: RpcParams): void;
|
|
18
20
|
normalizeOutboundMessagePayload(params: RpcParams, method?: string): void;
|
|
@@ -43,7 +45,8 @@ export declare class RpcPipeline {
|
|
|
43
45
|
isPullNamespaceCurrent(namespace: string): boolean;
|
|
44
46
|
invalidatePulls(): Promise<void>;
|
|
45
47
|
private pullInvalidationInProgress;
|
|
46
|
-
|
|
48
|
+
runPullNamespaceSerialized<T>(key: string, operation: () => Promise<T> | T, background?: boolean): Promise<T>;
|
|
49
|
+
runPullSerialized<T>(key: string, operation: () => Promise<T> | T, background?: boolean, namespaceOnly?: boolean): Promise<T>;
|
|
47
50
|
private executePullOperation;
|
|
48
51
|
private throwIfPullInvalidated;
|
|
49
52
|
yieldPullGate(key: string, nextKey?: string, background?: boolean): Promise<void>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as crypto from 'node:crypto';
|
|
2
|
-
import { normalizeSlotId, slotIsolationKey } from '../config.js';
|
|
2
|
+
import { _INTERNAL_MESSAGE_FLOW_LIMITS, normalizeSlotId, slotIsolationKey } from '../config.js';
|
|
3
3
|
import { certTimeError } from '../cert-utils.js';
|
|
4
4
|
import { orgRequestParams, validateOrgRequestJSON } from '../org-protocol.js';
|
|
5
5
|
import { canonicalJson as canonicalClientRequest } from '../v2/crypto/canonical.js';
|
|
@@ -115,7 +115,6 @@ function getCertFingerprint(certPem) {
|
|
|
115
115
|
/** 旧式 tryAcquirePullGate 的防并发窗口。 */
|
|
116
116
|
const PULL_GATE_STALE_MS = 35_000;
|
|
117
117
|
const PULL_GATE_OPERATION_TIMEOUT_MS = 35_000;
|
|
118
|
-
const PULL_GATE_MAX_ACTIVE = 4;
|
|
119
118
|
function sameIdentityAdmissionRejection(error, original) {
|
|
120
119
|
const errorCode = Number(error?.code);
|
|
121
120
|
const originalCode = Number(original?.code);
|
|
@@ -167,6 +166,12 @@ export class RpcPipeline {
|
|
|
167
166
|
this.runtime = runtime;
|
|
168
167
|
}
|
|
169
168
|
async call(method, params) {
|
|
169
|
+
return this._call(method, params);
|
|
170
|
+
}
|
|
171
|
+
async _callWithSent(method, params, onSent) {
|
|
172
|
+
return this._call(method, params, onSent);
|
|
173
|
+
}
|
|
174
|
+
async _call(method, params, onSent) {
|
|
170
175
|
const client = this.runtime.client;
|
|
171
176
|
const generation = client._delivery?.captureInlineAckGeneration?.();
|
|
172
177
|
const tStart = Date.now();
|
|
@@ -194,6 +199,23 @@ export class RpcPipeline {
|
|
|
194
199
|
const deferGroupReadyPostprocess = Boolean(p._defer_group_ready_postprocess);
|
|
195
200
|
delete p._defer_group_ready_postprocess;
|
|
196
201
|
const pullGateKey = this.pullGateKeyForCall(method, p);
|
|
202
|
+
if (client._p2pPeerPullEnabled && method === 'message.peers')
|
|
203
|
+
return await client._delivery.peers(p, rpcBackground);
|
|
204
|
+
if (client._p2pPeerPullEnabled && (method === 'message.pull' || method === 'message.v2.pull')) {
|
|
205
|
+
await client._ensureV2SessionReady('message.pull');
|
|
206
|
+
return await client._delivery.pullPeers(p, rpcBackground);
|
|
207
|
+
}
|
|
208
|
+
if (client._p2pPeerPullEnabled && method === 'message.history') {
|
|
209
|
+
await client._ensureV2SessionReady('message.history');
|
|
210
|
+
const key = this.pullGateKeyForCall(method, p);
|
|
211
|
+
return await this.runPullNamespaceSerialized(key, () => client._v2E2EE.peerHistoryV2(p), rpcBackground);
|
|
212
|
+
}
|
|
213
|
+
if (client._p2pPeerPullEnabled && (method === 'message.ack' || method === 'message.v2.ack')) {
|
|
214
|
+
const sender = String(p.sender_aid ?? '').trim();
|
|
215
|
+
if (!sender)
|
|
216
|
+
throw new ValidationError('peer ACK requires sender_aid');
|
|
217
|
+
return await client._v2E2EE.ackPeerV2(sender, requestedAckSeq || undefined, Array.isArray(p.volatile_cursors) ? p.volatile_cursors : [], Array.isArray(p.volatile_ids) ? p.volatile_ids : []);
|
|
218
|
+
}
|
|
197
219
|
const runWithPullResponseScope = async (operation) => {
|
|
198
220
|
const scope = pullGateNamespace || (pullGateKey ? this.pullScopeKey(pullGateKey) : '');
|
|
199
221
|
const wrapper = client._withPullResponseProcessing;
|
|
@@ -207,9 +229,13 @@ export class RpcPipeline {
|
|
|
207
229
|
lockedParams._pull_gate_namespace = this.pullScopeKey(pullGateKey);
|
|
208
230
|
if (pullBackground)
|
|
209
231
|
lockedParams._rpc_background = true;
|
|
232
|
+
else
|
|
233
|
+
lockedParams._rpc_foreground = true;
|
|
210
234
|
if (skipSendResultEnvelope)
|
|
211
235
|
lockedParams._skip_send_result_envelope = true;
|
|
212
|
-
|
|
236
|
+
const run = ['group.pull', 'group.v2.pull', 'group.history'].includes(method)
|
|
237
|
+
? this.runPullNamespaceSerialized.bind(this) : this.runPullSerialized.bind(this);
|
|
238
|
+
return await run(pullGateKey, async () => this.call(method, lockedParams), pullBackground);
|
|
213
239
|
}
|
|
214
240
|
if (method === 'message.send') {
|
|
215
241
|
const encrypt = p.encrypt ?? true;
|
|
@@ -222,6 +248,7 @@ export class RpcPipeline {
|
|
|
222
248
|
ttl: p.ttl,
|
|
223
249
|
protectedHeaders: client._protectedHeadersFromParams(p),
|
|
224
250
|
context: isJsonObject(p.context) ? p.context : undefined,
|
|
251
|
+
needRender: p.need_render,
|
|
225
252
|
}));
|
|
226
253
|
}
|
|
227
254
|
client._maybeAppendEchoTraceSend(p);
|
|
@@ -236,6 +263,7 @@ export class RpcPipeline {
|
|
|
236
263
|
timestamp: p.timestamp,
|
|
237
264
|
protectedHeaders: client._protectedHeadersFromParams(p),
|
|
238
265
|
context: isJsonObject(p.context) ? p.context : undefined,
|
|
266
|
+
needRender: p.need_render,
|
|
239
267
|
}));
|
|
240
268
|
}
|
|
241
269
|
client._maybeAppendEchoTraceSend(p);
|
|
@@ -298,12 +326,12 @@ export class RpcPipeline {
|
|
|
298
326
|
}
|
|
299
327
|
await client._ensureV2SessionReady('group.pull');
|
|
300
328
|
if (p.window_mode === 'tail') {
|
|
301
|
-
return await runWithPullResponseScope(() => client._v2E2EE.pullGroupV2TailInternal(p));
|
|
329
|
+
return await runWithPullResponseScope(() => client._v2E2EE.pullGroupV2TailInternal(p, false, true));
|
|
302
330
|
}
|
|
303
331
|
const hasExplicitAfterSeq = 'after_seq' in p || 'after_message_seq' in p;
|
|
304
332
|
const cursorParams = this.explicitGroupCursorParams(p);
|
|
305
333
|
const ownsCursor = Object.keys(cursorParams).length === 0 || this.groupCursorTargetsCurrentInstance(cursorParams);
|
|
306
|
-
const pullOpts = { gateLocked: true };
|
|
334
|
+
const pullOpts = { gateLocked: true, background: rpcBackground };
|
|
307
335
|
if (hasExplicitAfterSeq)
|
|
308
336
|
pullOpts.explicitAfterSeq = true;
|
|
309
337
|
if (p.force === true)
|
|
@@ -316,7 +344,7 @@ export class RpcPipeline {
|
|
|
316
344
|
pullOpts.wireGroupId = String(p.group_id).trim();
|
|
317
345
|
if (String(p.group_aid ?? '').trim())
|
|
318
346
|
pullOpts.groupAid = String(p.group_aid).trim();
|
|
319
|
-
const messages = await runWithPullResponseScope(() =>
|
|
347
|
+
const messages = await runWithPullResponseScope(() => client._pullGroupV2(String(p.group_id ?? p.group_aid), Number(p.after_seq ?? p.after_message_seq ?? 0) || 0, Number(p.limit ?? 50) || 50, pullOpts));
|
|
320
348
|
return { messages };
|
|
321
349
|
}
|
|
322
350
|
if (method === 'group.history') {
|
|
@@ -349,13 +377,15 @@ export class RpcPipeline {
|
|
|
349
377
|
client._clientLog.debug(`thought.get transport call start: method=${method}, params=${client._debugJson(client._messageEnvelopeFieldsForDebug(p))}`);
|
|
350
378
|
}
|
|
351
379
|
const invokeTransport = () => {
|
|
352
|
-
const request =
|
|
353
|
-
? (rpcBackground
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
:
|
|
380
|
+
const request = onSent
|
|
381
|
+
? client._transport['_callWithSent'](method, p, onSent, callTimeout, undefined, rpcBackground)
|
|
382
|
+
: callTimeout
|
|
383
|
+
? (rpcBackground
|
|
384
|
+
? client._transport.call(method, p, callTimeout, undefined, true)
|
|
385
|
+
: client._transport.call(method, p, callTimeout))
|
|
386
|
+
: (rpcBackground
|
|
387
|
+
? client._transport.call(method, p, undefined, undefined, true)
|
|
388
|
+
: client._transport.call(method, p));
|
|
359
389
|
return this.bindActivePullCancellation(method, p, request);
|
|
360
390
|
};
|
|
361
391
|
let result = await this.transportCallWithIdentityRecovery(invokeTransport, method, p);
|
|
@@ -392,8 +422,11 @@ export class RpcPipeline {
|
|
|
392
422
|
}
|
|
393
423
|
const p = { ...(params ?? {}) };
|
|
394
424
|
this.mergeInstanceProtectedHeaders(method, p);
|
|
395
|
-
const rpcBackground = Boolean(p.
|
|
425
|
+
const rpcBackground = !Boolean(p._rpc_foreground)
|
|
426
|
+
&& (Boolean(p._rpc_background)
|
|
427
|
+
|| (!['message.peers', 'message.pull', 'message.v2.pull', 'group.pull', 'group.v2.pull', 'group.history', 'group.pull_events'].includes(method) && client._backgroundRpcDepth > 0));
|
|
396
428
|
delete p._rpc_background;
|
|
429
|
+
delete p._rpc_foreground;
|
|
397
430
|
if (method === 'message.send' || method === 'group.send') {
|
|
398
431
|
this.normalizeOutboundMessagePayload(p, method);
|
|
399
432
|
const messageId = String(p.message_id ?? '').trim();
|
|
@@ -430,6 +463,9 @@ export class RpcPipeline {
|
|
|
430
463
|
}
|
|
431
464
|
}
|
|
432
465
|
validateOutboundCall(method, params) {
|
|
466
|
+
if ((method === 'message.send' || method === 'group.send') && params.need_render !== undefined && typeof params.need_render !== 'boolean') {
|
|
467
|
+
throw new ValidationError('need_render must be a boolean');
|
|
468
|
+
}
|
|
433
469
|
if (method === 'message.send') {
|
|
434
470
|
this.validateMessageRecipient(params.to);
|
|
435
471
|
// 校验目标 AID 格式(拒绝 __system__ 等非法格式)
|
|
@@ -492,7 +528,7 @@ export class RpcPipeline {
|
|
|
492
528
|
}
|
|
493
529
|
}
|
|
494
530
|
injectMessageCursorContext(method, params) {
|
|
495
|
-
if (!['message.pull', 'message.v2.pull', 'message.ack', 'message.v2.ack'].includes(method)) {
|
|
531
|
+
if (!['message.pull', 'message.v2.pull', 'message.history', 'message.ack', 'message.v2.ack', 'message.peers'].includes(method)) {
|
|
496
532
|
return;
|
|
497
533
|
}
|
|
498
534
|
const client = this.runtime.client;
|
|
@@ -505,6 +541,19 @@ export class RpcPipeline {
|
|
|
505
541
|
}
|
|
506
542
|
params.device_id = client._deviceId;
|
|
507
543
|
params.slot_id = client._slotId;
|
|
544
|
+
if (client._p2pPeerPullEnabled) {
|
|
545
|
+
if (params.cursor_scope !== undefined && params.cursor_scope !== 'peer')
|
|
546
|
+
throw new ValidationError('new SDK requires peer cursor_scope');
|
|
547
|
+
if (params.sender_aid !== undefined)
|
|
548
|
+
validateAIDFormat(params.sender_aid, 'sender_aid');
|
|
549
|
+
params.cursor_scope = 'peer';
|
|
550
|
+
if ((method === 'message.pull' || method === 'message.v2.pull') && params.sender_aid && !('after_volatile_cursor' in params)) {
|
|
551
|
+
const cursor = client._delivery.peerVolatilePullCursor(String(params.sender_aid));
|
|
552
|
+
if (cursor)
|
|
553
|
+
params.after_volatile_cursor = cursor;
|
|
554
|
+
}
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
508
557
|
if ((method === 'message.pull' || method === 'message.v2.pull') && !('after_volatile_cursor' in params)) {
|
|
509
558
|
const cursor = String(client._delivery.volatilePullCursor?.() ?? '').trim();
|
|
510
559
|
if (cursor)
|
|
@@ -610,7 +659,10 @@ export class RpcPipeline {
|
|
|
610
659
|
cursor = `after=${String(params.after_seq ?? 0)}`;
|
|
611
660
|
}
|
|
612
661
|
const limit = mode === 'forward' ? (Number(params.limit ?? 50) || 50) : params.limit;
|
|
613
|
-
|
|
662
|
+
if (client._p2pPeerPullEnabled && !params.sender_aid)
|
|
663
|
+
return '';
|
|
664
|
+
const namespace = client._p2pPeerPullEnabled ? client._delivery.peerNamespace(String(params.sender_aid)) : `p2p:${client._aid}`;
|
|
665
|
+
return `${namespace}|mode=${mode}|cursor=${cursor}|volatile=${String(params.after_volatile_cursor ?? '')}|force=${String(Boolean(params.force))}|limit=${String(limit)}`;
|
|
614
666
|
}
|
|
615
667
|
if (method === 'group.pull' || method === 'group.v2.pull' || method === 'group.history') {
|
|
616
668
|
const groupId = String(params.group_id ?? params.group_aid ?? '').trim();
|
|
@@ -655,14 +707,15 @@ export class RpcPipeline {
|
|
|
655
707
|
void key;
|
|
656
708
|
return 'pull';
|
|
657
709
|
}
|
|
658
|
-
pullGateState(key) {
|
|
659
|
-
const name = this.pullGateName(key);
|
|
710
|
+
pullGateState(key, namespaceOnly = false) {
|
|
711
|
+
const name = namespaceOnly ? 'pull-namespace' : this.pullGateName(key);
|
|
660
712
|
let state = this.pullGateStates.get(name);
|
|
661
713
|
if (!state) {
|
|
662
|
-
state = { activeByNamespace: new Map(), foreground: [], background: [], byKey: new Map(), lifecycle: new Map(), watchdog: null };
|
|
714
|
+
state = { networkLimited: !namespaceOnly, activeByNamespace: new Map(), foreground: [], background: [], backgroundPeerDispatches: 0, byKey: new Map(), lifecycle: new Map(), watchdog: null };
|
|
663
715
|
this.pullGateStates.set(name, state);
|
|
664
716
|
}
|
|
665
|
-
|
|
717
|
+
if (state.networkLimited)
|
|
718
|
+
this.startPullGateWatchdog(state, name);
|
|
666
719
|
return state;
|
|
667
720
|
}
|
|
668
721
|
pullGateOperationTimeoutMs() {
|
|
@@ -740,9 +793,11 @@ export class RpcPipeline {
|
|
|
740
793
|
}
|
|
741
794
|
hasPullActivity(namespace, includePending = true) {
|
|
742
795
|
const ns = String(namespace ?? '').trim();
|
|
743
|
-
if ((!ns.startsWith('p2p:') && !ns.startsWith('group:')) || this.hasInlineRealtimeGuard(ns))
|
|
796
|
+
if ((!ns.startsWith('p2p:') && !ns.startsWith('p2p.peer.v1/') && !ns.startsWith('group:')) || this.hasInlineRealtimeGuard(ns))
|
|
744
797
|
return true;
|
|
745
798
|
const client = this.runtime.client;
|
|
799
|
+
if (client._delivery?.hasPeerPageActivity?.(ns))
|
|
800
|
+
return true;
|
|
746
801
|
if ((client._pullResponseKeys.get(ns) ?? 0) > 0)
|
|
747
802
|
return true;
|
|
748
803
|
if (includePending && Number(client._pendingP2pPullUpper?.get?.(ns) ?? 0) > 0)
|
|
@@ -769,7 +824,7 @@ export class RpcPipeline {
|
|
|
769
824
|
}
|
|
770
825
|
async tryRunInlineRealtime(namespace, seq, operation) {
|
|
771
826
|
const ns = String(namespace ?? '').trim();
|
|
772
|
-
if ((!ns.startsWith('p2p:') && !ns.startsWith('group:'))
|
|
827
|
+
if ((!ns.startsWith('p2p:') && !ns.startsWith('p2p.peer.v1/') && !ns.startsWith('group:'))
|
|
773
828
|
|| !Number.isSafeInteger(seq) || seq <= 0 || typeof operation !== 'function'
|
|
774
829
|
|| this.hasPullActivity(ns)) {
|
|
775
830
|
return { acquired: false };
|
|
@@ -780,12 +835,11 @@ export class RpcPipeline {
|
|
|
780
835
|
}
|
|
781
836
|
finally {
|
|
782
837
|
this.inlineRealtimeScopes.delete(ns);
|
|
783
|
-
const state
|
|
784
|
-
if (state) {
|
|
838
|
+
for (const state of this.pullGateStates.values()) {
|
|
785
839
|
this.drainPullGate(state);
|
|
786
|
-
this.runtime.client._delivery?.onPullGateIdle?.(ns);
|
|
787
840
|
this.armQueuedPullTimers(state);
|
|
788
841
|
}
|
|
842
|
+
this.runtime.client._delivery?.onPullGateIdle?.(ns);
|
|
789
843
|
}
|
|
790
844
|
}
|
|
791
845
|
tryAcquirePullGate(key) {
|
|
@@ -825,8 +879,10 @@ export class RpcPipeline {
|
|
|
825
879
|
const ns = this.pullScopeKey(namespace);
|
|
826
880
|
if (!ns)
|
|
827
881
|
return true;
|
|
828
|
-
|
|
829
|
-
|
|
882
|
+
return [...this.pullGateStates.values()].every((state) => {
|
|
883
|
+
const active = state.activeByNamespace.get(ns);
|
|
884
|
+
return !active || active.namespace !== ns || (!active.timedOut && !active.invalidated);
|
|
885
|
+
});
|
|
830
886
|
}
|
|
831
887
|
invalidatePulls() {
|
|
832
888
|
if (this.pullInvalidationWait)
|
|
@@ -859,6 +915,7 @@ export class RpcPipeline {
|
|
|
859
915
|
}
|
|
860
916
|
state.foreground = state.foreground.filter((job) => !jobs.has(job));
|
|
861
917
|
state.background = state.background.filter((job) => !jobs.has(job));
|
|
918
|
+
state.backgroundPeerDispatches = 0;
|
|
862
919
|
for (const [key, job] of state.byKey.entries()) {
|
|
863
920
|
if (jobs.has(job) && !job.running)
|
|
864
921
|
state.byKey.delete(key);
|
|
@@ -877,7 +934,10 @@ export class RpcPipeline {
|
|
|
877
934
|
pullInvalidationInProgress() {
|
|
878
935
|
return this.pullInvalidationWait !== null;
|
|
879
936
|
}
|
|
880
|
-
async
|
|
937
|
+
async runPullNamespaceSerialized(key, operation, background = false) {
|
|
938
|
+
return await this.runPullSerialized(key, operation, background, true);
|
|
939
|
+
}
|
|
940
|
+
async runPullSerialized(key, operation, background = false, namespaceOnly = false) {
|
|
881
941
|
if (this.runtime.client._dispatcher?._isApplicationHandler?.()) {
|
|
882
942
|
throw new Error('pull cannot wait inside an application handler');
|
|
883
943
|
}
|
|
@@ -893,7 +953,7 @@ export class RpcPipeline {
|
|
|
893
953
|
throw error;
|
|
894
954
|
}
|
|
895
955
|
}
|
|
896
|
-
const state = this.pullGateState(key);
|
|
956
|
+
const state = this.pullGateState(key, namespaceOnly);
|
|
897
957
|
const namespace = this.pullScopeKey(key);
|
|
898
958
|
const active = [...state.activeByNamespace.values()].find((job) => job.key === key && !job.timedOut && !job.invalidated) ?? null;
|
|
899
959
|
const queuedForeground = state.foreground.find((job) => job.key === key && !job.timedOut && !job.invalidated);
|
|
@@ -937,7 +997,8 @@ export class RpcPipeline {
|
|
|
937
997
|
queue.push(job);
|
|
938
998
|
state.byKey.set(key, job);
|
|
939
999
|
this.drainPullGate(state);
|
|
940
|
-
|
|
1000
|
+
if (state.networkLimited)
|
|
1001
|
+
this.checkPullGate(state, this.pullGateName(key));
|
|
941
1002
|
return await promise;
|
|
942
1003
|
}
|
|
943
1004
|
async executePullOperation(operation, background) {
|
|
@@ -1000,15 +1061,40 @@ export class RpcPipeline {
|
|
|
1000
1061
|
state.lifecycle.set(ns, lifecycle);
|
|
1001
1062
|
}
|
|
1002
1063
|
drainPullGate(state) {
|
|
1003
|
-
const
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1064
|
+
const peerForward = (job) => job.background && job.namespace.startsWith('p2p.peer.v1/')
|
|
1065
|
+
&& job.key.includes('|mode=forward|') && !job.key.includes('|force=true|');
|
|
1066
|
+
const priority = (job) => peerForward(job)
|
|
1067
|
+
? this.runtime.client._delivery?.peerPullPriority?.(job.namespace) ?? null : null;
|
|
1068
|
+
const runnable = (candidate) => (!this.hasInlineRealtimeGuard(this.pullScopeKey(candidate.key))
|
|
1069
|
+
&& !state.activeByNamespace.has(candidate.namespace));
|
|
1070
|
+
const takeRunnable = (queue, background = false) => {
|
|
1071
|
+
let index = queue.findIndex(runnable);
|
|
1072
|
+
if (index < 0)
|
|
1073
|
+
return;
|
|
1074
|
+
if (background && peerForward(queue[index])
|
|
1075
|
+
&& (state.backgroundPeerDispatches + 1) % _INTERNAL_MESSAGE_FLOW_LIMITS.pullMaxInflight !== 0) {
|
|
1076
|
+
let best = priority(queue[index]);
|
|
1077
|
+
if (best !== null) {
|
|
1078
|
+
for (let next = index + 1; next < queue.length; next += 1) {
|
|
1079
|
+
const hint = priority(queue[next]);
|
|
1080
|
+
if (hint === null)
|
|
1081
|
+
break;
|
|
1082
|
+
if (runnable(queue[next]) && hint < best) {
|
|
1083
|
+
best = hint;
|
|
1084
|
+
index = next;
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
const job = queue.splice(index, 1)[0];
|
|
1090
|
+
if (background && peerForward(job))
|
|
1091
|
+
state.backgroundPeerDispatches += 1;
|
|
1092
|
+
return job;
|
|
1007
1093
|
};
|
|
1008
|
-
while (state.activeByNamespace.size <
|
|
1094
|
+
while (state.activeByNamespace.size < _INTERNAL_MESSAGE_FLOW_LIMITS.pullMaxInflight) {
|
|
1009
1095
|
const foregroundJob = takeRunnable(state.foreground);
|
|
1010
1096
|
const foregroundDrained = foregroundJob !== undefined && state.foreground.length === 0;
|
|
1011
|
-
const job = foregroundJob ?? takeRunnable(state.background);
|
|
1097
|
+
const job = foregroundJob ?? takeRunnable(state.background, true);
|
|
1012
1098
|
if (!job)
|
|
1013
1099
|
break;
|
|
1014
1100
|
state.activeByNamespace.set(job.namespace, job);
|
|
@@ -1031,7 +1117,7 @@ export class RpcPipeline {
|
|
|
1031
1117
|
continue;
|
|
1032
1118
|
}
|
|
1033
1119
|
job.running = true;
|
|
1034
|
-
const operationPromise = this.executePullOperation(job.operation, job.background);
|
|
1120
|
+
const operationPromise = this.executePullOperation(job.operation, state.networkLimited && job.background);
|
|
1035
1121
|
let failed = false;
|
|
1036
1122
|
void operationPromise
|
|
1037
1123
|
.then((value) => { if (!job.timedOut && !job.invalidated)
|