@peerbit/shared-log 15.0.0 → 16.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/checked-prune.d.ts.map +1 -1
- package/dist/src/checked-prune.js +12 -0
- package/dist/src/checked-prune.js.map +1 -1
- package/dist/src/index.d.ts +7 -13
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +81 -598
- package/dist/src/index.js.map +1 -1
- package/dist/src/instance-lifecycle.d.ts.map +1 -1
- package/dist/src/instance-lifecycle.js +9 -0
- package/dist/src/instance-lifecycle.js.map +1 -1
- package/dist/src/peer-session.d.ts.map +1 -1
- package/dist/src/peer-session.js +9 -0
- package/dist/src/peer-session.js.map +1 -1
- package/dist/src/pid.d.ts +0 -2
- package/dist/src/pid.d.ts.map +1 -1
- package/dist/src/pid.js +0 -5
- package/dist/src/pid.js.map +1 -1
- package/dist/src/replication-announcement.d.ts +3 -106
- package/dist/src/replication-announcement.d.ts.map +1 -1
- package/dist/src/replication-announcement.js +0 -521
- package/dist/src/replication-announcement.js.map +1 -1
- package/dist/src/replication-info-v2-receive.d.ts +14 -43
- package/dist/src/replication-info-v2-receive.d.ts.map +1 -1
- package/dist/src/replication-info-v2-receive.js +24 -199
- package/dist/src/replication-info-v2-receive.js.map +1 -1
- package/dist/src/replication-info-v2-send.d.ts +0 -1
- package/dist/src/replication-info-v2-send.d.ts.map +1 -1
- package/dist/src/replication-info-v2-send.js +0 -6
- package/dist/src/replication-info-v2-send.js.map +1 -1
- package/dist/src/replication.d.ts +0 -1
- package/dist/src/replication.d.ts.map +1 -1
- package/dist/src/replication.js +2 -17
- package/dist/src/replication.js.map +1 -1
- package/dist/src/role.d.ts +0 -4
- package/dist/src/role.d.ts.map +1 -1
- package/dist/src/role.js +0 -9
- package/dist/src/role.js.map +1 -1
- package/dist/src/sync/factory.d.ts +0 -1
- package/dist/src/sync/factory.d.ts.map +1 -1
- package/dist/src/sync/factory.js +20 -36
- package/dist/src/sync/factory.js.map +1 -1
- package/package.json +8 -8
- package/src/checked-prune.ts +12 -0
- package/src/index.ts +104 -817
- package/src/instance-lifecycle.ts +9 -0
- package/src/peer-session.ts +9 -0
- package/src/pid.ts +0 -6
- package/src/replication-announcement.ts +8 -739
- package/src/replication-info-v2-receive.ts +25 -271
- package/src/replication-info-v2-send.ts +0 -7
- package/src/replication.ts +1 -20
- package/src/role.ts +0 -13
- package/src/sync/factory.ts +24 -38
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { type PublicSignKey } from "@peerbit/crypto";
|
|
2
|
-
import {
|
|
3
|
-
type LegacyReplicationInfoMessage = AllReplicatingSegmentsMessage | AddedReplicationSegmentMessage | StoppedReplicating;
|
|
2
|
+
import { type ReplicationInfoV2Message, RequestReplicationInfoV2Message } from "./replication.js";
|
|
4
3
|
export type ReplicationInfoV2ReceivePhase = "awaiting-full" | "active" | "resync";
|
|
5
4
|
type LocalCapabilityReady = {
|
|
6
5
|
peerHash: string;
|
|
@@ -23,13 +22,11 @@ type LocalCapabilityReadyProperties = {
|
|
|
23
22
|
};
|
|
24
23
|
export type ReplicationInfoV2LocalCapabilityAdvertisementHandle = {
|
|
25
24
|
firstAttempt: Promise<void>;
|
|
26
|
-
releaseLegacyBarrier(): void;
|
|
27
25
|
};
|
|
28
26
|
export type ReplicationInfoV2LocalCapabilityContext = {
|
|
29
27
|
peerHash: string;
|
|
30
28
|
target: PublicSignKey;
|
|
31
29
|
lifecycleSignal: AbortSignal;
|
|
32
|
-
legacyBarrierReleased: boolean;
|
|
33
30
|
};
|
|
34
31
|
export type ReplicationInfoV2LocalCapabilityAdvertisement = {
|
|
35
32
|
peerHash: string;
|
|
@@ -74,18 +71,6 @@ export type ReplicationInfoV2ReceiveState = {
|
|
|
74
71
|
requestsSinceCapabilityRefresh: number;
|
|
75
72
|
requestParked: boolean;
|
|
76
73
|
capabilityRefreshRequired: boolean;
|
|
77
|
-
legacyFallbackTimer?: ReturnType<typeof setTimeout>;
|
|
78
|
-
legacyFallbackFingerprint?: Uint8Array;
|
|
79
|
-
legacyFallbackTimestamp?: bigint;
|
|
80
|
-
legacyFallbackAmbiguous: boolean;
|
|
81
|
-
lastCommittedTransportTimestamp?: bigint;
|
|
82
|
-
recentCommittedPayloads: Array<{
|
|
83
|
-
fingerprint: Uint8Array;
|
|
84
|
-
transportTimestamp: bigint;
|
|
85
|
-
}>;
|
|
86
|
-
lastLegacyObservationTimestamp?: bigint;
|
|
87
|
-
lastLegacyObservationFingerprint?: Uint8Array;
|
|
88
|
-
lastLegacyObservationAmbiguous: boolean;
|
|
89
74
|
reservedAdmission?: ReplicationInfoV2ReceiveAdmission;
|
|
90
75
|
};
|
|
91
76
|
export type ReplicationInfoV2ReceiveAdmission = {
|
|
@@ -121,7 +106,6 @@ export type ReplicationInfoV2ReceiveDeps = {
|
|
|
121
106
|
requestRetryMs?: number;
|
|
122
107
|
maxRequestRetryMs?: number;
|
|
123
108
|
requestMaxAttempts?: number;
|
|
124
|
-
legacyFallbackDelayMs?: number;
|
|
125
109
|
};
|
|
126
110
|
/**
|
|
127
111
|
* Authenticated receive grants and sender-authoritative ordering for
|
|
@@ -131,6 +115,14 @@ export type ReplicationInfoV2ReceiveDeps = {
|
|
|
131
115
|
export declare class ReplicationInfoV2ReceiveCoordinator {
|
|
132
116
|
private readonly deps;
|
|
133
117
|
_receiveStates: Map<string, ReplicationInfoV2ReceiveState>;
|
|
118
|
+
/**
|
|
119
|
+
* Post-B12 V2 resync memory: sessions that have already taken one full
|
|
120
|
+
* replication-info snapshot. Two load-bearing reads, both in
|
|
121
|
+
* observeCapability: phase selection (a remembered session opens in
|
|
122
|
+
* "resync" instead of "awaiting-full"), and capability refresh (the
|
|
123
|
+
* preserveCutover decision, which keeps the memory only when a re-advert
|
|
124
|
+
* arrives under the same session with a ready sender).
|
|
125
|
+
*/
|
|
134
126
|
_cutoverPeerSessions: WeakSet<object>;
|
|
135
127
|
_localCapabilityReadyBySession: WeakMap<object, LocalCapabilityReady>;
|
|
136
128
|
_localCapabilityContextBySession: WeakMap<object, ReplicationInfoV2LocalCapabilityContext>;
|
|
@@ -140,13 +132,12 @@ export declare class ReplicationInfoV2ReceiveCoordinator {
|
|
|
140
132
|
private readonly requestRetryMs;
|
|
141
133
|
private readonly maxRequestRetryMs;
|
|
142
134
|
private readonly requestMaxAttempts;
|
|
143
|
-
private readonly legacyFallbackDelayMs;
|
|
144
135
|
constructor(deps: ReplicationInfoV2ReceiveDeps);
|
|
145
136
|
resetForOpen(): void;
|
|
146
137
|
clearForClose(): void;
|
|
147
138
|
clearPeer(peerHash: string, expectedSession?: object): void;
|
|
148
139
|
/** Revoke an unauthenticated or downgraded capability generation. */
|
|
149
|
-
revokePeerCapability(peerHash: string
|
|
140
|
+
revokePeerCapability(peerHash: string): void;
|
|
150
141
|
private clearState;
|
|
151
142
|
private clearLocalCapabilityAdvertisement;
|
|
152
143
|
private isLocalCapabilityAdvertisementOwnerCurrent;
|
|
@@ -156,10 +147,9 @@ export declare class ReplicationInfoV2ReceiveCoordinator {
|
|
|
156
147
|
private armLocalCapabilityAdvertisement;
|
|
157
148
|
private runLocalCapabilityAdvertisement;
|
|
158
149
|
/**
|
|
159
|
-
* Start local authenticated-apply advertisement
|
|
160
|
-
*
|
|
161
|
-
*
|
|
162
|
-
* after the host releases the legacy barrier. Failed attempts leave one
|
|
150
|
+
* Start local authenticated-apply advertisement. Readiness is promoted as
|
|
151
|
+
* soon as the ACK lands (B12: the legacy publication this once ordered
|
|
152
|
+
* behind a two-phase barrier is retired). Failed attempts leave one
|
|
163
153
|
* exact-session worker retrying with capped exponential backoff.
|
|
164
154
|
*/
|
|
165
155
|
advertiseLocalCapability(properties: {
|
|
@@ -168,13 +158,10 @@ export declare class ReplicationInfoV2ReceiveCoordinator {
|
|
|
168
158
|
receiveEpoch: object | null;
|
|
169
159
|
signal: AbortSignal;
|
|
170
160
|
}): ReplicationInfoV2LocalCapabilityAdvertisementHandle;
|
|
171
|
-
private releaseLocalCapabilityLegacyBarrier;
|
|
172
161
|
private promoteLocalCapabilityAdvertisement;
|
|
173
162
|
/**
|
|
174
163
|
* Re-advertise one exact current recovery epoch from the stable membership
|
|
175
|
-
* context captured during opening.
|
|
176
|
-
* recovery never bypasses a legacy snapshot or role publication still in
|
|
177
|
-
* progress.
|
|
164
|
+
* context captured during opening.
|
|
178
165
|
*/
|
|
179
166
|
reAdvertiseLocalCapabilityForRecovery(properties: {
|
|
180
167
|
peerHash: string;
|
|
@@ -226,7 +213,6 @@ export declare class ReplicationInfoV2ReceiveCoordinator {
|
|
|
226
213
|
receiveEpoch: object | null;
|
|
227
214
|
}): boolean;
|
|
228
215
|
private transitionToResync;
|
|
229
|
-
isLegacyCutover(peerSession: object | null): boolean;
|
|
230
216
|
prepare(message: ReplicationInfoV2Message, properties: {
|
|
231
217
|
from: PublicSignKey;
|
|
232
218
|
peerSession: object;
|
|
@@ -243,21 +229,6 @@ export declare class ReplicationInfoV2ReceiveCoordinator {
|
|
|
243
229
|
transportTimestamp: bigint;
|
|
244
230
|
}): ReplicationInfoV2ReceiveAdmission | undefined;
|
|
245
231
|
release(admission: ReplicationInfoV2ReceiveAdmission): void;
|
|
246
|
-
/**
|
|
247
|
-
* B9 can lose its sender grant while keeping the topic session open. Its
|
|
248
|
-
* unmatched legacy sidecar is the compatibility signal to re-handshake; a
|
|
249
|
-
* matching V2 payload before or after the legacy copy suppresses the timer.
|
|
250
|
-
*/
|
|
251
|
-
noteLegacyAnnouncement(properties: {
|
|
252
|
-
peerHash: string;
|
|
253
|
-
peerSession: object;
|
|
254
|
-
receiveEpoch: object | null;
|
|
255
|
-
senderTransportSession: bigint;
|
|
256
|
-
transportTimestamp: bigint;
|
|
257
|
-
message: LegacyReplicationInfoMessage;
|
|
258
|
-
}): boolean;
|
|
259
|
-
private armLegacyFallback;
|
|
260
|
-
private clearLegacyFallback;
|
|
261
232
|
isAdmissionCurrent(admission: ReplicationInfoV2ReceiveAdmission): boolean;
|
|
262
233
|
commit(admission: ReplicationInfoV2ReceiveAdmission): boolean;
|
|
263
234
|
requireFullAfterFailure(admission: ReplicationInfoV2ReceiveAdmission): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"replication-info-v2-receive.d.ts","sourceRoot":"","sources":["../../src/replication-info-v2-receive.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,aAAa,EAA2B,MAAM,iBAAiB,CAAC;AAM9E,OAAO,
|
|
1
|
+
{"version":3,"file":"replication-info-v2-receive.d.ts","sourceRoot":"","sources":["../../src/replication-info-v2-receive.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,7 +8,6 @@ const REQUIRED_SENDER_CAPABILITIES = SYNC_CAPABILITY_REPLICATION_INFO_V2_DECODE
|
|
|
8
8
|
const DEFAULT_REQUEST_RETRY_MS = 1_000;
|
|
9
9
|
const DEFAULT_MAX_REQUEST_RETRY_MS = 30_000;
|
|
10
10
|
const DEFAULT_REQUEST_MAX_ATTEMPTS = 7;
|
|
11
|
-
const DEFAULT_LEGACY_FALLBACK_DELAY_MS = 5_000;
|
|
12
11
|
const MAX_U64 = (1n << 64n) - 1n;
|
|
13
12
|
const MAX_BACKOFF_EXPONENT = 20;
|
|
14
13
|
const bytesEqual = (left, right) => {
|
|
@@ -22,6 +21,10 @@ const bytesEqual = (left, right) => {
|
|
|
22
21
|
}
|
|
23
22
|
return true;
|
|
24
23
|
};
|
|
24
|
+
// Q4 (B12): fingerprints keep constructing the legacy-class canonical forms.
|
|
25
|
+
// They are byte-stable local-only hash inputs, never sent; these are the only
|
|
26
|
+
// sanctioned legacy-frame construction sites in src (see the no-legacy-
|
|
27
|
+
// machinery source ratchet's narrowed whitelist).
|
|
25
28
|
const replicationInfoPayloadFingerprint = (message) => {
|
|
26
29
|
const canonical = message instanceof FullReplicationInfoV2Message
|
|
27
30
|
? new AllReplicatingSegmentsMessage({ segments: message.segments })
|
|
@@ -40,6 +43,14 @@ const replicationInfoPayloadFingerprint = (message) => {
|
|
|
40
43
|
export class ReplicationInfoV2ReceiveCoordinator {
|
|
41
44
|
deps;
|
|
42
45
|
_receiveStates;
|
|
46
|
+
/**
|
|
47
|
+
* Post-B12 V2 resync memory: sessions that have already taken one full
|
|
48
|
+
* replication-info snapshot. Two load-bearing reads, both in
|
|
49
|
+
* observeCapability: phase selection (a remembered session opens in
|
|
50
|
+
* "resync" instead of "awaiting-full"), and capability refresh (the
|
|
51
|
+
* preserveCutover decision, which keeps the memory only when a re-advert
|
|
52
|
+
* arrives under the same session with a ready sender).
|
|
53
|
+
*/
|
|
43
54
|
_cutoverPeerSessions;
|
|
44
55
|
_localCapabilityReadyBySession;
|
|
45
56
|
_localCapabilityContextBySession;
|
|
@@ -49,14 +60,12 @@ export class ReplicationInfoV2ReceiveCoordinator {
|
|
|
49
60
|
requestRetryMs;
|
|
50
61
|
maxRequestRetryMs;
|
|
51
62
|
requestMaxAttempts;
|
|
52
|
-
legacyFallbackDelayMs;
|
|
53
63
|
constructor(deps) {
|
|
54
64
|
this.deps = deps;
|
|
55
65
|
this.now = deps.now ?? Date.now;
|
|
56
66
|
this.requestRetryMs = Math.max(1, deps.requestRetryMs ?? DEFAULT_REQUEST_RETRY_MS);
|
|
57
67
|
this.maxRequestRetryMs = Math.max(this.requestRetryMs, deps.maxRequestRetryMs ?? DEFAULT_MAX_REQUEST_RETRY_MS);
|
|
58
68
|
this.requestMaxAttempts = Math.max(1, Math.floor(deps.requestMaxAttempts ?? DEFAULT_REQUEST_MAX_ATTEMPTS));
|
|
59
|
-
this.legacyFallbackDelayMs = Math.max(this.requestRetryMs, deps.legacyFallbackDelayMs ?? DEFAULT_LEGACY_FALLBACK_DELAY_MS);
|
|
60
69
|
this._receiveStates = new Map();
|
|
61
70
|
this._cutoverPeerSessions = new WeakSet();
|
|
62
71
|
this._localCapabilityReadyBySession = new WeakMap();
|
|
@@ -108,25 +117,23 @@ export class ReplicationInfoV2ReceiveCoordinator {
|
|
|
108
117
|
}
|
|
109
118
|
}
|
|
110
119
|
/** Revoke an unauthenticated or downgraded capability generation. */
|
|
111
|
-
revokePeerCapability(peerHash
|
|
120
|
+
revokePeerCapability(peerHash) {
|
|
112
121
|
const state = this._receiveStates.get(peerHash);
|
|
113
122
|
if (!state) {
|
|
114
123
|
return;
|
|
115
124
|
}
|
|
116
125
|
this.clearState(state);
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
126
|
+
// Unconditional: the revoked session must lose its resync memory so a
|
|
127
|
+
// re-advert starts from the first phase again. (This used to sit behind
|
|
128
|
+
// an opt-out parameter that defaulted to true, had no else-arm, and that
|
|
129
|
+
// no caller ever overrode.)
|
|
130
|
+
this._cutoverPeerSessions.delete(state.peerSession);
|
|
120
131
|
}
|
|
121
132
|
clearState(state) {
|
|
122
133
|
if (state.requestTimer) {
|
|
123
134
|
clearTimeout(state.requestTimer);
|
|
124
135
|
state.requestTimer = undefined;
|
|
125
136
|
}
|
|
126
|
-
if (state.legacyFallbackTimer) {
|
|
127
|
-
clearTimeout(state.legacyFallbackTimer);
|
|
128
|
-
state.legacyFallbackTimer = undefined;
|
|
129
|
-
}
|
|
130
137
|
state.controller.abort();
|
|
131
138
|
state.version++;
|
|
132
139
|
if (this._receiveStates.get(state.peerHash) === state) {
|
|
@@ -186,9 +193,6 @@ export class ReplicationInfoV2ReceiveCoordinator {
|
|
|
186
193
|
if (state.timer || state.inFlight || state.ready) {
|
|
187
194
|
return;
|
|
188
195
|
}
|
|
189
|
-
if (state.acknowledgedReady && !state.context.legacyBarrierReleased) {
|
|
190
|
-
return;
|
|
191
|
-
}
|
|
192
196
|
if (!this.isLocalCapabilityAdvertisementOwnerCurrent(state)) {
|
|
193
197
|
this.clearLocalCapabilityAdvertisement(state);
|
|
194
198
|
return;
|
|
@@ -229,9 +233,7 @@ export class ReplicationInfoV2ReceiveCoordinator {
|
|
|
229
233
|
return;
|
|
230
234
|
}
|
|
231
235
|
if (state.acknowledgedReady) {
|
|
232
|
-
|
|
233
|
-
this.promoteLocalCapabilityAdvertisement(state);
|
|
234
|
-
}
|
|
236
|
+
this.promoteLocalCapabilityAdvertisement(state);
|
|
235
237
|
return;
|
|
236
238
|
}
|
|
237
239
|
if (!this.isLocalCapabilityAdvertisementReadyOpen(state)) {
|
|
@@ -284,19 +286,16 @@ export class ReplicationInfoV2ReceiveCoordinator {
|
|
|
284
286
|
}
|
|
285
287
|
else if (this.isLocalCapabilityAdvertisementGenerationCurrent(state) &&
|
|
286
288
|
!state.ready) {
|
|
287
|
-
|
|
288
|
-
this.armLocalCapabilityAdvertisement(state);
|
|
289
|
-
}
|
|
289
|
+
this.armLocalCapabilityAdvertisement(state);
|
|
290
290
|
}
|
|
291
291
|
});
|
|
292
292
|
state.inFlight = operation;
|
|
293
293
|
await operation;
|
|
294
294
|
}
|
|
295
295
|
/**
|
|
296
|
-
* Start local authenticated-apply advertisement
|
|
297
|
-
*
|
|
298
|
-
*
|
|
299
|
-
* after the host releases the legacy barrier. Failed attempts leave one
|
|
296
|
+
* Start local authenticated-apply advertisement. Readiness is promoted as
|
|
297
|
+
* soon as the ACK lands (B12: the legacy publication this once ordered
|
|
298
|
+
* behind a two-phase barrier is retired). Failed attempts leave one
|
|
300
299
|
* exact-session worker retrying with capped exponential backoff.
|
|
301
300
|
*/
|
|
302
301
|
advertiseLocalCapability(properties) {
|
|
@@ -307,7 +306,6 @@ export class ReplicationInfoV2ReceiveCoordinator {
|
|
|
307
306
|
!this.deps.isReceiveEpochCurrent(peerHash, properties.receiveEpoch)) {
|
|
308
307
|
return {
|
|
309
308
|
firstAttempt: Promise.resolve(),
|
|
310
|
-
releaseLegacyBarrier: () => { },
|
|
311
309
|
};
|
|
312
310
|
}
|
|
313
311
|
let context = this._localCapabilityContextBySession.get(properties.peerSession);
|
|
@@ -317,7 +315,6 @@ export class ReplicationInfoV2ReceiveCoordinator {
|
|
|
317
315
|
context.lifecycleSignal !== properties.signal)) {
|
|
318
316
|
return {
|
|
319
317
|
firstAttempt: Promise.resolve(),
|
|
320
|
-
releaseLegacyBarrier: () => { },
|
|
321
318
|
};
|
|
322
319
|
}
|
|
323
320
|
if (!context) {
|
|
@@ -325,7 +322,6 @@ export class ReplicationInfoV2ReceiveCoordinator {
|
|
|
325
322
|
peerHash,
|
|
326
323
|
target: properties.target,
|
|
327
324
|
lifecycleSignal: properties.signal,
|
|
328
|
-
legacyBarrierReleased: false,
|
|
329
325
|
};
|
|
330
326
|
this._localCapabilityContextBySession.set(properties.peerSession, context);
|
|
331
327
|
}
|
|
@@ -350,7 +346,6 @@ export class ReplicationInfoV2ReceiveCoordinator {
|
|
|
350
346
|
context) {
|
|
351
347
|
return {
|
|
352
348
|
firstAttempt: Promise.resolve(),
|
|
353
|
-
releaseLegacyBarrier: () => { },
|
|
354
349
|
};
|
|
355
350
|
}
|
|
356
351
|
if (!state) {
|
|
@@ -377,36 +372,13 @@ export class ReplicationInfoV2ReceiveCoordinator {
|
|
|
377
372
|
}
|
|
378
373
|
const firstAttempt = state.firstAttempt ??
|
|
379
374
|
(state.firstAttempt = this.runLocalCapabilityAdvertisement(state));
|
|
380
|
-
const advertisement = state;
|
|
381
375
|
return {
|
|
382
376
|
firstAttempt,
|
|
383
|
-
releaseLegacyBarrier: () => this.releaseLocalCapabilityLegacyBarrier(advertisement.peerSession, context),
|
|
384
377
|
};
|
|
385
378
|
}
|
|
386
|
-
releaseLocalCapabilityLegacyBarrier(peerSession, context) {
|
|
387
|
-
if (context.legacyBarrierReleased) {
|
|
388
|
-
return;
|
|
389
|
-
}
|
|
390
|
-
if (this._localCapabilityContextBySession.get(peerSession) !== context ||
|
|
391
|
-
context.lifecycleSignal.aborted ||
|
|
392
|
-
this.deps.isClosed() ||
|
|
393
|
-
!this.deps.isPeerSessionCurrent(context.peerHash, peerSession)) {
|
|
394
|
-
return;
|
|
395
|
-
}
|
|
396
|
-
context.legacyBarrierReleased = true;
|
|
397
|
-
const state = this._localCapabilityAdvertisementsByPeer.get(context.peerHash);
|
|
398
|
-
if (state?.peerSession === peerSession && state.context === context) {
|
|
399
|
-
if (!this.isLocalCapabilityAdvertisementOwnerCurrent(state)) {
|
|
400
|
-
this.clearLocalCapabilityAdvertisement(state);
|
|
401
|
-
return;
|
|
402
|
-
}
|
|
403
|
-
this.promoteLocalCapabilityAdvertisement(state);
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
379
|
promoteLocalCapabilityAdvertisement(state) {
|
|
407
380
|
const ready = state.acknowledgedReady;
|
|
408
381
|
if (state.ready ||
|
|
409
|
-
!state.context.legacyBarrierReleased ||
|
|
410
382
|
!ready ||
|
|
411
383
|
ready.receiveEpoch !== state.receiveEpoch ||
|
|
412
384
|
ready.advertisement !== state ||
|
|
@@ -433,9 +405,7 @@ export class ReplicationInfoV2ReceiveCoordinator {
|
|
|
433
405
|
}
|
|
434
406
|
/**
|
|
435
407
|
* Re-advertise one exact current recovery epoch from the stable membership
|
|
436
|
-
* context captured during opening.
|
|
437
|
-
* recovery never bypasses a legacy snapshot or role publication still in
|
|
438
|
-
* progress.
|
|
408
|
+
* context captured during opening.
|
|
439
409
|
*/
|
|
440
410
|
reAdvertiseLocalCapabilityForRecovery(properties) {
|
|
441
411
|
const context = this._localCapabilityContextBySession.get(properties.peerSession);
|
|
@@ -587,9 +557,6 @@ export class ReplicationInfoV2ReceiveCoordinator {
|
|
|
587
557
|
requestsSinceCapabilityRefresh: 0,
|
|
588
558
|
requestParked: false,
|
|
589
559
|
capabilityRefreshRequired: retainedCutover,
|
|
590
|
-
legacyFallbackAmbiguous: false,
|
|
591
|
-
recentCommittedPayloads: [],
|
|
592
|
-
lastLegacyObservationAmbiguous: false,
|
|
593
560
|
};
|
|
594
561
|
this._receiveStates.set(peerHash, state);
|
|
595
562
|
const ready = this._localCapabilityReadyBySession.get(peerSession);
|
|
@@ -697,9 +664,6 @@ export class ReplicationInfoV2ReceiveCoordinator {
|
|
|
697
664
|
this.armRequest(state, 0);
|
|
698
665
|
}
|
|
699
666
|
}
|
|
700
|
-
isLegacyCutover(peerSession) {
|
|
701
|
-
return peerSession !== null && this._cutoverPeerSessions.has(peerSession);
|
|
702
|
-
}
|
|
703
667
|
prepare(message, properties) {
|
|
704
668
|
const peerHash = properties.from.hashcode();
|
|
705
669
|
const state = this._receiveStates.get(peerHash);
|
|
@@ -809,10 +773,6 @@ export class ReplicationInfoV2ReceiveCoordinator {
|
|
|
809
773
|
clearTimeout(state.requestTimer);
|
|
810
774
|
state.requestTimer = undefined;
|
|
811
775
|
}
|
|
812
|
-
if (state.legacyFallbackTimer) {
|
|
813
|
-
clearTimeout(state.legacyFallbackTimer);
|
|
814
|
-
state.legacyFallbackTimer = undefined;
|
|
815
|
-
}
|
|
816
776
|
return admission;
|
|
817
777
|
}
|
|
818
778
|
release(admission) {
|
|
@@ -843,126 +803,6 @@ export class ReplicationInfoV2ReceiveCoordinator {
|
|
|
843
803
|
// worker so the exact current generation cannot become stranded.
|
|
844
804
|
this.armRequest(state, 0);
|
|
845
805
|
}
|
|
846
|
-
if (currentState === state &&
|
|
847
|
-
this.isStateCurrent(state) &&
|
|
848
|
-
state.phase === "active" &&
|
|
849
|
-
state.legacyFallbackFingerprint !== undefined) {
|
|
850
|
-
// A reservation also pauses compat sidecar recovery. Matching commits
|
|
851
|
-
// clear the evidence; an uncommitted or non-matching frame restores its
|
|
852
|
-
// bounded fallback without invalidating work in the host apply lane.
|
|
853
|
-
this.armLegacyFallback(state);
|
|
854
|
-
}
|
|
855
|
-
}
|
|
856
|
-
/**
|
|
857
|
-
* B9 can lose its sender grant while keeping the topic session open. Its
|
|
858
|
-
* unmatched legacy sidecar is the compatibility signal to re-handshake; a
|
|
859
|
-
* matching V2 payload before or after the legacy copy suppresses the timer.
|
|
860
|
-
*/
|
|
861
|
-
noteLegacyAnnouncement(properties) {
|
|
862
|
-
const state = this._receiveStates.get(properties.peerHash);
|
|
863
|
-
if (!state ||
|
|
864
|
-
state.peerSession !== properties.peerSession ||
|
|
865
|
-
state.receiveEpoch !== properties.receiveEpoch ||
|
|
866
|
-
state.senderTransportSession !== properties.senderTransportSession ||
|
|
867
|
-
!this._cutoverPeerSessions.has(properties.peerSession) ||
|
|
868
|
-
!this.isStateCurrent(state)) {
|
|
869
|
-
return false;
|
|
870
|
-
}
|
|
871
|
-
const fingerprint = replicationInfoPayloadFingerprint(properties.message);
|
|
872
|
-
if (state.lastCommittedTransportTimestamp !== undefined &&
|
|
873
|
-
properties.transportTimestamp < state.lastCommittedTransportTimestamp) {
|
|
874
|
-
return true;
|
|
875
|
-
}
|
|
876
|
-
if (state.recentCommittedPayloads.some((committed) => properties.transportTimestamp <= committed.transportTimestamp &&
|
|
877
|
-
bytesEqual(committed.fingerprint, fingerprint))) {
|
|
878
|
-
return true;
|
|
879
|
-
}
|
|
880
|
-
if (state.lastLegacyObservationTimestamp !== undefined) {
|
|
881
|
-
if (properties.transportTimestamp < state.lastLegacyObservationTimestamp) {
|
|
882
|
-
return true;
|
|
883
|
-
}
|
|
884
|
-
if (properties.transportTimestamp === state.lastLegacyObservationTimestamp) {
|
|
885
|
-
if (state.lastLegacyObservationAmbiguous ||
|
|
886
|
-
(state.lastLegacyObservationFingerprint !== undefined &&
|
|
887
|
-
bytesEqual(state.lastLegacyObservationFingerprint, fingerprint))) {
|
|
888
|
-
return true;
|
|
889
|
-
}
|
|
890
|
-
state.lastLegacyObservationAmbiguous = true;
|
|
891
|
-
}
|
|
892
|
-
else {
|
|
893
|
-
state.lastLegacyObservationTimestamp = properties.transportTimestamp;
|
|
894
|
-
state.lastLegacyObservationFingerprint = fingerprint.slice();
|
|
895
|
-
state.lastLegacyObservationAmbiguous = false;
|
|
896
|
-
}
|
|
897
|
-
}
|
|
898
|
-
else {
|
|
899
|
-
state.lastLegacyObservationTimestamp = properties.transportTimestamp;
|
|
900
|
-
state.lastLegacyObservationFingerprint = fingerprint.slice();
|
|
901
|
-
state.lastLegacyObservationAmbiguous = false;
|
|
902
|
-
}
|
|
903
|
-
const reserved = this._reservedAdmissionsByPeer.get(properties.peerHash);
|
|
904
|
-
if (reserved?.state === state &&
|
|
905
|
-
!bytesEqual(reserved.payloadFingerprint, fingerprint)) {
|
|
906
|
-
// A legacy sidecar observed while a different V2 payload is applying
|
|
907
|
-
// cannot be erased by that commit. The transport has already ACKed the
|
|
908
|
-
// sidecar, so require one authoritative successor after release.
|
|
909
|
-
reserved.resyncAfterRelease = true;
|
|
910
|
-
}
|
|
911
|
-
if (!state.legacyFallbackFingerprint) {
|
|
912
|
-
state.legacyFallbackFingerprint = fingerprint;
|
|
913
|
-
state.legacyFallbackTimestamp = properties.transportTimestamp;
|
|
914
|
-
state.legacyFallbackAmbiguous = false;
|
|
915
|
-
}
|
|
916
|
-
else {
|
|
917
|
-
if (!bytesEqual(state.legacyFallbackFingerprint, fingerprint)) {
|
|
918
|
-
state.legacyFallbackAmbiguous = true;
|
|
919
|
-
}
|
|
920
|
-
if (state.legacyFallbackTimestamp === undefined ||
|
|
921
|
-
properties.transportTimestamp > state.legacyFallbackTimestamp) {
|
|
922
|
-
state.legacyFallbackTimestamp = properties.transportTimestamp;
|
|
923
|
-
}
|
|
924
|
-
}
|
|
925
|
-
if (state.phase !== "active") {
|
|
926
|
-
if (state.requestParked) {
|
|
927
|
-
this.transitionToResync(state, {
|
|
928
|
-
force: true,
|
|
929
|
-
refreshCapability: true,
|
|
930
|
-
});
|
|
931
|
-
}
|
|
932
|
-
return true;
|
|
933
|
-
}
|
|
934
|
-
if (state.legacyFallbackTimer) {
|
|
935
|
-
return true;
|
|
936
|
-
}
|
|
937
|
-
this.armLegacyFallback(state);
|
|
938
|
-
return true;
|
|
939
|
-
}
|
|
940
|
-
armLegacyFallback(state) {
|
|
941
|
-
if (state.legacyFallbackTimer ||
|
|
942
|
-
state.phase !== "active" ||
|
|
943
|
-
state.legacyFallbackFingerprint === undefined ||
|
|
944
|
-
this._reservedAdmissionsByPeer.has(state.peerHash)) {
|
|
945
|
-
return;
|
|
946
|
-
}
|
|
947
|
-
state.legacyFallbackTimer = setTimeout(() => {
|
|
948
|
-
state.legacyFallbackTimer = undefined;
|
|
949
|
-
if (this.isStateCurrent(state) && state.phase === "active") {
|
|
950
|
-
this.transitionToResync(state, {
|
|
951
|
-
force: true,
|
|
952
|
-
refreshCapability: true,
|
|
953
|
-
});
|
|
954
|
-
}
|
|
955
|
-
}, this.legacyFallbackDelayMs);
|
|
956
|
-
state.legacyFallbackTimer.unref?.();
|
|
957
|
-
}
|
|
958
|
-
clearLegacyFallback(state) {
|
|
959
|
-
if (state.legacyFallbackTimer) {
|
|
960
|
-
clearTimeout(state.legacyFallbackTimer);
|
|
961
|
-
state.legacyFallbackTimer = undefined;
|
|
962
|
-
}
|
|
963
|
-
state.legacyFallbackFingerprint = undefined;
|
|
964
|
-
state.legacyFallbackTimestamp = undefined;
|
|
965
|
-
state.legacyFallbackAmbiguous = false;
|
|
966
806
|
}
|
|
967
807
|
isAdmissionCurrent(admission) {
|
|
968
808
|
const { state } = admission;
|
|
@@ -1000,21 +840,6 @@ export class ReplicationInfoV2ReceiveCoordinator {
|
|
|
1000
840
|
state.requestsSinceCapabilityRefresh = 0;
|
|
1001
841
|
state.requestParked = false;
|
|
1002
842
|
state.capabilityRefreshRequired = false;
|
|
1003
|
-
state.lastCommittedTransportTimestamp = admission.transportTimestamp;
|
|
1004
|
-
state.recentCommittedPayloads.push({
|
|
1005
|
-
fingerprint: admission.payloadFingerprint.slice(),
|
|
1006
|
-
transportTimestamp: admission.transportTimestamp,
|
|
1007
|
-
});
|
|
1008
|
-
if (state.recentCommittedPayloads.length > 8) {
|
|
1009
|
-
state.recentCommittedPayloads.shift();
|
|
1010
|
-
}
|
|
1011
|
-
if ((state.legacyFallbackTimestamp !== undefined &&
|
|
1012
|
-
admission.transportTimestamp > state.legacyFallbackTimestamp) ||
|
|
1013
|
-
(!state.legacyFallbackAmbiguous &&
|
|
1014
|
-
state.legacyFallbackFingerprint !== undefined &&
|
|
1015
|
-
bytesEqual(state.legacyFallbackFingerprint, admission.payloadFingerprint))) {
|
|
1016
|
-
this.clearLegacyFallback(state);
|
|
1017
|
-
}
|
|
1018
843
|
if (state.requestTimer) {
|
|
1019
844
|
clearTimeout(state.requestTimer);
|
|
1020
845
|
state.requestTimer = undefined;
|