@serfab/cadre-core 1.7.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -6
- package/dist/cadre-node.d.ts +527 -206
- package/dist/cadre-node.js +1084 -528
- package/dist/cadre-node.js.map +1 -1
- package/dist/control-authorization.d.ts +2 -2
- package/dist/control-authorization.js +1 -0
- package/dist/control-authorization.js.map +1 -1
- package/dist/control-cohort.d.ts +6 -0
- package/dist/control-cohort.js +6 -0
- package/dist/control-cohort.js.map +1 -1
- package/dist/control-database.d.ts +46 -8
- package/dist/control-database.js +97 -18
- package/dist/control-database.js.map +1 -1
- package/dist/control-formation-recorder.d.ts +37 -14
- package/dist/control-formation-recorder.js +60 -10
- package/dist/control-formation-recorder.js.map +1 -1
- package/dist/control-read-retry.d.ts +13 -12
- package/dist/control-read-retry.js +14 -12
- package/dist/control-read-retry.js.map +1 -1
- package/dist/control-schema.d.ts +1 -1
- package/dist/control-schema.js +67 -5
- package/dist/control-schema.js.map +1 -1
- package/dist/control-stream.d.ts +9 -1
- package/dist/control-stream.js +24 -1
- package/dist/control-stream.js.map +1 -1
- package/dist/control-write-retry.d.ts +12 -2
- package/dist/control-write-retry.js +13 -2
- package/dist/control-write-retry.js.map +1 -1
- package/dist/delegate-admission.d.ts +11 -8
- package/dist/delegate-admission.js +19 -11
- package/dist/delegate-admission.js.map +1 -1
- package/dist/diagnostics/connection-path.d.ts +0 -7
- package/dist/diagnostics/connection-path.js +0 -7
- package/dist/diagnostics/connection-path.js.map +1 -1
- package/dist/formation-approval.d.ts +7 -0
- package/dist/formation-approval.js +9 -3
- package/dist/formation-approval.js.map +1 -1
- package/dist/fs-atomic.d.ts +11 -2
- package/dist/fs-atomic.js +13 -3
- package/dist/fs-atomic.js.map +1 -1
- package/dist/hibernation-manager.d.ts +111 -8
- package/dist/hibernation-manager.js +234 -49
- package/dist/hibernation-manager.js.map +1 -1
- package/dist/index.d.ts +10 -10
- package/dist/index.js +25 -20
- package/dist/index.js.map +1 -1
- package/dist/joined-strand-store.d.ts +90 -25
- package/dist/joined-strand-store.js +223 -55
- package/dist/joined-strand-store.js.map +1 -1
- package/dist/key-store-file.js +14 -5
- package/dist/key-store-file.js.map +1 -1
- package/dist/link-budget.d.ts +367 -69
- package/dist/link-budget.js +375 -72
- package/dist/link-budget.js.map +1 -1
- package/dist/membership-connection-gater.d.ts +30 -43
- package/dist/membership-connection-gater.js +31 -42
- package/dist/membership-connection-gater.js.map +1 -1
- package/dist/node-local-snapshot.d.ts +6 -4
- package/dist/node-local-snapshot.js +7 -3
- package/dist/node-local-snapshot.js.map +1 -1
- package/dist/peer-dial.d.ts +24 -4
- package/dist/peer-dial.js +74 -5
- package/dist/peer-dial.js.map +1 -1
- package/dist/peer-join-backfill.d.ts +2 -10
- package/dist/peer-join-backfill.js +8 -8
- package/dist/peer-join-backfill.js.map +1 -1
- package/dist/push-fanout.d.ts +6 -0
- package/dist/push-fanout.js +6 -0
- package/dist/push-fanout.js.map +1 -1
- package/dist/relay-reservation.d.ts +3 -1
- package/dist/relay-reservation.js +3 -1
- package/dist/relay-reservation.js.map +1 -1
- package/dist/relay-server.d.ts +79 -0
- package/dist/relay-server.js +74 -0
- package/dist/relay-server.js.map +1 -0
- package/dist/seed-bootstrap.d.ts +57 -4
- package/dist/seed-bootstrap.js +107 -83
- package/dist/seed-bootstrap.js.map +1 -1
- package/dist/storage-scope.d.ts +33 -17
- package/dist/storage-scope.js +44 -23
- package/dist/storage-scope.js.map +1 -1
- package/dist/strand-addr-protocol.d.ts +58 -21
- package/dist/strand-addr-protocol.js +133 -85
- package/dist/strand-addr-protocol.js.map +1 -1
- package/dist/strand-database.d.ts +20 -2
- package/dist/strand-database.js +42 -5
- package/dist/strand-database.js.map +1 -1
- package/dist/strand-first-sync-gate.d.ts +59 -21
- package/dist/strand-first-sync-gate.js +58 -19
- package/dist/strand-first-sync-gate.js.map +1 -1
- package/dist/strand-formation-deadlines.d.ts +151 -0
- package/dist/strand-formation-deadlines.js +171 -0
- package/dist/strand-formation-deadlines.js.map +1 -0
- package/dist/strand-formation-manager.d.ts +63 -30
- package/dist/strand-formation-manager.js +67 -41
- package/dist/strand-formation-manager.js.map +1 -1
- package/dist/strand-formation-protocol.d.ts +45 -46
- package/dist/strand-formation-protocol.js +62 -126
- package/dist/strand-formation-protocol.js.map +1 -1
- package/dist/strand-fret-addrs.d.ts +54 -0
- package/dist/strand-fret-addrs.js +108 -0
- package/dist/strand-fret-addrs.js.map +1 -0
- package/dist/strand-instance-manager.d.ts +122 -44
- package/dist/strand-instance-manager.js +270 -114
- package/dist/strand-instance-manager.js.map +1 -1
- package/dist/strand-membership-writer.d.ts +6 -0
- package/dist/strand-membership-writer.js +11 -0
- package/dist/strand-membership-writer.js.map +1 -1
- package/dist/strand-network-state-file.d.ts +12 -0
- package/dist/strand-network-state-file.js +38 -0
- package/dist/strand-network-state-file.js.map +1 -0
- package/dist/strand-network-state.d.ts +111 -0
- package/dist/strand-network-state.js +191 -0
- package/dist/strand-network-state.js.map +1 -0
- package/dist/strand-revocation-enforcer.js +2 -1
- package/dist/strand-revocation-enforcer.js.map +1 -1
- package/dist/strand-solicitation.d.ts +36 -20
- package/dist/strand-solicitation.js +4 -4
- package/dist/strand-solicitation.js.map +1 -1
- package/dist/strand-wake-protocol.d.ts +80 -23
- package/dist/strand-wake-protocol.js +89 -64
- package/dist/strand-wake-protocol.js.map +1 -1
- package/dist/types.d.ts +148 -61
- package/dist/types.js +4 -3
- package/dist/types.js.map +1 -1
- package/package.json +11 -10
- package/src/cadre-node.ts +8400 -7776
- package/src/control-authorization.ts +2 -1
- package/src/control-cohort.ts +6 -0
- package/src/control-database.ts +122 -18
- package/src/control-formation-recorder.ts +354 -305
- package/src/control-read-retry.ts +14 -12
- package/src/control-schema.ts +67 -5
- package/src/control-stream.ts +25 -1
- package/src/control-write-retry.ts +13 -2
- package/src/delegate-admission.ts +23 -13
- package/src/diagnostics/connection-path.ts +0 -7
- package/src/formation-approval.ts +610 -604
- package/src/fs-atomic.ts +14 -4
- package/src/hibernation-manager.ts +638 -437
- package/src/index.ts +43 -65
- package/src/joined-strand-store.ts +247 -57
- package/src/key-store-file.ts +14 -5
- package/src/link-budget.ts +393 -74
- package/src/membership-connection-gater.ts +31 -45
- package/src/node-local-snapshot.ts +12 -7
- package/src/peer-dial.ts +81 -7
- package/src/peer-join-backfill.ts +10 -9
- package/src/push-fanout.ts +6 -0
- package/src/relay-reservation.ts +3 -1
- package/src/relay-server.ts +98 -0
- package/src/seed-bootstrap.ts +133 -91
- package/src/storage-scope.ts +44 -23
- package/src/strand-addr-protocol.ts +547 -458
- package/src/strand-database.ts +287 -242
- package/src/strand-first-sync-gate.ts +58 -19
- package/src/strand-formation-deadlines.ts +227 -0
- package/src/strand-formation-manager.ts +700 -647
- package/src/strand-formation-protocol.ts +106 -154
- package/src/strand-fret-addrs.ts +145 -0
- package/src/strand-instance-manager.ts +307 -140
- package/src/strand-membership-writer.ts +12 -0
- package/src/strand-network-state-file.ts +40 -0
- package/src/strand-network-state.ts +243 -0
- package/src/strand-revocation-enforcer.ts +2 -1
- package/src/strand-solicitation.ts +519 -500
- package/src/strand-wake-protocol.ts +401 -355
- package/src/types.ts +150 -61
- package/dist/strand-peer-book-file.d.ts +0 -12
- package/dist/strand-peer-book-file.js +0 -37
- package/dist/strand-peer-book-file.js.map +0 -1
- package/dist/strand-peer-book-protocol.d.ts +0 -159
- package/dist/strand-peer-book-protocol.js +0 -360
- package/dist/strand-peer-book-protocol.js.map +0 -1
- package/dist/strand-peer-book-swap.d.ts +0 -104
- package/dist/strand-peer-book-swap.js +0 -284
- package/dist/strand-peer-book-swap.js.map +0 -1
- package/dist/strand-peer-book.d.ts +0 -159
- package/dist/strand-peer-book.js +0 -354
- package/dist/strand-peer-book.js.map +0 -1
- package/dist/strand-peer-observer.d.ts +0 -88
- package/dist/strand-peer-observer.js +0 -180
- package/dist/strand-peer-observer.js.map +0 -1
- package/src/strand-peer-book-file.ts +0 -39
- package/src/strand-peer-book-protocol.ts +0 -463
- package/src/strand-peer-book-swap.ts +0 -338
- package/src/strand-peer-book.ts +0 -468
- package/src/strand-peer-observer.ts +0 -235
|
@@ -26,8 +26,9 @@
|
|
|
26
26
|
*/
|
|
27
27
|
import debug from 'debug';
|
|
28
28
|
import { decodeLengthPrefixedFrame } from './seed-bootstrap.js';
|
|
29
|
-
import {
|
|
29
|
+
import { exchangeFrame, readStreamToEnd, replyAndClose } from './control-stream.js';
|
|
30
30
|
import { tryAddrsInTurn } from './peer-dial.js';
|
|
31
|
+
import { relayedRequestBudgetMs } from './link-budget.js';
|
|
31
32
|
const log = debug('sereus:cadre:strand-wake');
|
|
32
33
|
/** Protocol id for control-network push-wake (parallel to `/sereus/seed/1.0.0`). */
|
|
33
34
|
export const WAKE_PROTOCOL = '/sereus/strand-wake/1.0.0';
|
|
@@ -37,36 +38,57 @@ export const WAKE_PROTOCOL = '/sereus/strand-wake/1.0.0';
|
|
|
37
38
|
* bytes a peer can make the receiver buffer per stream.
|
|
38
39
|
*/
|
|
39
40
|
const MAX_WAKE_SIZE = 64 * 1024;
|
|
40
|
-
/** Default time to wait for the ack before abandoning ONE wake dial attempt (ms). */
|
|
41
|
-
const DEFAULT_WAKE_TIMEOUT_MS = 10000;
|
|
42
41
|
/**
|
|
43
|
-
* Default
|
|
44
|
-
*
|
|
42
|
+
* Default deadline for ONE wake attempt — dial, request, ack — at the default declared link
|
|
43
|
+
* (ms): `relayedRequestBudgetMs` in `link-budget.ts`, because the target may be reachable
|
|
44
|
+
* only through a relay and the attempt has to open that connection before the exchange.
|
|
45
|
+
* {@link dialWake} derives it from {@link DialWakeOptions.linkRoundTripMs} instead when given.
|
|
46
|
+
*
|
|
47
|
+
* It holds only link work because the receiver acks as soon as it has DECIDED, before the
|
|
48
|
+
* wake itself runs ({@link StrandWakeService.processWakeRequest}).
|
|
49
|
+
*
|
|
50
|
+
* NOTE: the receiver's membership check (two live control reads) runs inside this deadline and
|
|
51
|
+
* is not counted. In steady state those reads touch only held blocks and do not consult the
|
|
52
|
+
* cohort. If a wake or address request is seen timing out while the receiver's membership read
|
|
53
|
+
* is consulting, count one membership decision in this deadline or answer the check from the
|
|
54
|
+
* materialized authorized-peer snapshot. See docs/cadre-consistency.md → "Deadlines Over
|
|
55
|
+
* Optimystic's Reads and Commits".
|
|
56
|
+
*/
|
|
57
|
+
export const DEFAULT_WAKE_TIMEOUT_MS = relayedRequestBudgetMs();
|
|
58
|
+
/**
|
|
59
|
+
* Whole attempts one {@link dialWake} call budgets for: a stale signaling address, then the
|
|
60
|
+
* direct address that works.
|
|
61
|
+
*/
|
|
62
|
+
export const WAKE_DIAL_ATTEMPTS = 2;
|
|
63
|
+
/**
|
|
64
|
+
* Default budget for a WHOLE {@link dialWake} call at the default declared link, in ms —
|
|
65
|
+
* every candidate address together, not each one: {@link WAKE_DIAL_ATTEMPTS} attempt
|
|
66
|
+
* deadlines.
|
|
45
67
|
*
|
|
46
68
|
* Without it the cost of a wake is (candidate count × {@link
|
|
47
69
|
* DEFAULT_WAKE_TIMEOUT_MS}), a number nothing chooses or bounds. That is not
|
|
48
70
|
* hypothetical: an address behind a dropped NAT mapping, or any host that
|
|
49
71
|
* blackholes rather than sending a RST, burns its full attempt timeout instead
|
|
50
|
-
* of failing in milliseconds, so a
|
|
51
|
-
* five-address one costs 50 s.
|
|
72
|
+
* of failing in milliseconds, so a five-address peer would cost five attempts.
|
|
52
73
|
*
|
|
53
74
|
* This makes the TARGET PEER the unit rather than the address — the same
|
|
54
75
|
* decision, for the same reason, as
|
|
55
76
|
* `DEFAULT_CONTROL_COHORT_DIAL_TIMEOUT_MS` in `peer-dial.ts`, though not the same
|
|
56
|
-
*
|
|
77
|
+
* count: that one is sized to fit several dead addresses ahead of a working one,
|
|
57
78
|
* while a wake target is expected to be awake and reachable on its first or second
|
|
58
|
-
* address.
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
79
|
+
* address. Two whole attempts so a reachable peer whose signaling address is stale
|
|
80
|
+
* still gets a genuine try at its direct one; a peer needing longer than that is
|
|
81
|
+
* not "asleep and reachable", which is the only case a wake is for. The last
|
|
82
|
+
* attempt inside the budget gets whatever remains of it, so the call returns at
|
|
83
|
+
* the budget, not past it.
|
|
63
84
|
*
|
|
64
85
|
* Override per call with {@link DialWakeOptions.budgetMs} — tests that drive
|
|
65
86
|
* dead addresses on purpose set it low so a dial's duration is a chosen number
|
|
66
87
|
* rather than a transitive libp2p default stretched by machine load.
|
|
67
88
|
*/
|
|
68
|
-
export const DEFAULT_WAKE_DIAL_BUDGET_MS =
|
|
89
|
+
export const DEFAULT_WAKE_DIAL_BUDGET_MS = WAKE_DIAL_ATTEMPTS * DEFAULT_WAKE_TIMEOUT_MS;
|
|
69
90
|
/** Default time the receiver waits for an inbound wake frame before aborting (ms). */
|
|
91
|
+
// eslint-disable-next-line no-restricted-syntax -- link-independent: a receiver cap on one small request frame on a stream the peer already opened; it bounds a peer that opens a stream and never sends, not the dial
|
|
70
92
|
const DEFAULT_WAKE_READ_TIMEOUT_MS = 10000;
|
|
71
93
|
/** Default cap on concurrent inbound wake streams a single peer can pin open. */
|
|
72
94
|
const DEFAULT_MAX_CONCURRENT_WAKES = 100;
|
|
@@ -84,8 +106,8 @@ async function readFrame(stream, timeoutMs) {
|
|
|
84
106
|
/**
|
|
85
107
|
* Receiver side of the push-wake protocol. Registers a `WAKE_PROTOCOL` handler
|
|
86
108
|
* on the control node and, for each inbound {@link WakeRequest}, gates on cadre
|
|
87
|
-
* membership,
|
|
88
|
-
*
|
|
109
|
+
* membership, replies with a {@link WakeAck}, and starts resuming the named
|
|
110
|
+
* strand if it is hibernating/idle and we participate in it.
|
|
89
111
|
*/
|
|
90
112
|
export class StrandWakeService {
|
|
91
113
|
constructor(options) {
|
|
@@ -100,18 +122,22 @@ export class StrandWakeService {
|
|
|
100
122
|
get activeCount() {
|
|
101
123
|
return this.activeStreams;
|
|
102
124
|
}
|
|
103
|
-
/**
|
|
104
|
-
|
|
105
|
-
|
|
125
|
+
/**
|
|
126
|
+
* Register the wake protocol handler on the control node. Rejects when libp2p
|
|
127
|
+
* refuses the registration; the node reference is kept only once the handler
|
|
128
|
+
* is in place.
|
|
129
|
+
*/
|
|
130
|
+
async initialize(node) {
|
|
106
131
|
// `runOnLimitedConnection: true` is REQUIRED for the relay path: a NAT'd
|
|
107
132
|
// receiver is reached over a circuit-relay connection, which libp2p marks
|
|
108
133
|
// "limited" (the relay caps its data/duration). Without this the receiver
|
|
109
134
|
// would refuse the inbound wake stream on exactly the connection the
|
|
110
135
|
// protocol is designed to use (see the relay note on `dialWake`).
|
|
111
|
-
|
|
136
|
+
await node.handle(WAKE_PROTOCOL, async (rawStream, rawConnection) => {
|
|
112
137
|
const remotePeerId = rawConnection.remotePeer.toString();
|
|
113
138
|
await this.handleStream(rawStream, remotePeerId);
|
|
114
139
|
}, { runOnLimitedConnection: true });
|
|
140
|
+
this.node = node;
|
|
115
141
|
log('StrandWakeService registered handler: %s', WAKE_PROTOCOL);
|
|
116
142
|
}
|
|
117
143
|
/** Unregister the handler and release the node reference. */
|
|
@@ -123,7 +149,7 @@ export class StrandWakeService {
|
|
|
123
149
|
}
|
|
124
150
|
}
|
|
125
151
|
/**
|
|
126
|
-
* Read the inbound request, decide
|
|
152
|
+
* Read the inbound request, decide the wake, and write the ack.
|
|
127
153
|
*
|
|
128
154
|
* Three hardening layers, all reported as a non-accepting ack rather than a
|
|
129
155
|
* dropped/hung stream: a concurrency cap (over {@link maxConcurrent}, reply
|
|
@@ -135,58 +161,41 @@ export class StrandWakeService {
|
|
|
135
161
|
log('Incoming wake request from: %s', remotePeerId);
|
|
136
162
|
if (this.activeStreams >= this.maxConcurrent) {
|
|
137
163
|
log('Rejecting wake from %s: %d concurrent streams at cap %d', remotePeerId, this.activeStreams, this.maxConcurrent);
|
|
138
|
-
|
|
139
|
-
try {
|
|
140
|
-
writeFrame(stream, ack);
|
|
141
|
-
}
|
|
142
|
-
catch {
|
|
143
|
-
// Ignore send errors on the reject path.
|
|
144
|
-
}
|
|
145
|
-
try {
|
|
146
|
-
await stream.close();
|
|
147
|
-
}
|
|
148
|
-
catch {
|
|
149
|
-
// Ignore close errors.
|
|
150
|
-
}
|
|
164
|
+
await replyAndClose(stream, { accepted: false, reason: 'Too many concurrent wake requests' }, 'Wake');
|
|
151
165
|
return;
|
|
152
166
|
}
|
|
153
167
|
this.activeStreams++;
|
|
168
|
+
try {
|
|
169
|
+
await replyAndClose(stream, await this.answerStream(stream, remotePeerId), 'Wake');
|
|
170
|
+
}
|
|
171
|
+
finally {
|
|
172
|
+
this.activeStreams--;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/** Read and decide one inbound request; any failure becomes a non-accepting ack. */
|
|
176
|
+
async answerStream(stream, remotePeerId) {
|
|
154
177
|
try {
|
|
155
178
|
const request = await readFrame(stream, this.readTimeoutMs);
|
|
156
|
-
|
|
157
|
-
writeFrame(stream, ack);
|
|
179
|
+
return await this.processWakeRequest(request, remotePeerId);
|
|
158
180
|
}
|
|
159
181
|
catch (err) {
|
|
160
182
|
log('Error handling wake request from %s: %o', remotePeerId, err);
|
|
161
|
-
|
|
162
|
-
accepted: false,
|
|
163
|
-
reason: err instanceof Error ? err.message : 'Unknown error',
|
|
164
|
-
};
|
|
165
|
-
try {
|
|
166
|
-
writeFrame(stream, ack);
|
|
167
|
-
}
|
|
168
|
-
catch {
|
|
169
|
-
// Ignore send errors on the error path.
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
finally {
|
|
173
|
-
this.activeStreams--;
|
|
174
|
-
try {
|
|
175
|
-
await stream.close();
|
|
176
|
-
}
|
|
177
|
-
catch {
|
|
178
|
-
// Ignore close errors.
|
|
179
|
-
}
|
|
183
|
+
return { accepted: false, reason: err instanceof Error ? err.message : 'Unknown error' };
|
|
180
184
|
}
|
|
181
185
|
}
|
|
182
186
|
/**
|
|
183
|
-
* Decide
|
|
187
|
+
* Decide the wake for a decoded request and start it. Exposed (not private) so
|
|
184
188
|
* the decision matrix can be unit-tested directly.
|
|
185
189
|
*
|
|
186
190
|
* - Non-member sender → rejected (`accepted: false`).
|
|
187
191
|
* - Unknown / not-participated strand → rejected.
|
|
188
|
-
* - Hibernating or idle strand →
|
|
192
|
+
* - Hibernating or idle strand → `accepted` with that status, and a wake started.
|
|
189
193
|
* - Already-live strand → no-op, `accepted` with current status.
|
|
194
|
+
*
|
|
195
|
+
* The wake is not awaited, so the ack means "a wake was started", not "the
|
|
196
|
+
* strand is up". Awaiting it would put the whole resume — a sibling address
|
|
197
|
+
* collection, a strand node build, a relay reservation drive — inside the
|
|
198
|
+
* sender's attempt deadline, coupling that deadline to this node's own budgets.
|
|
190
199
|
*/
|
|
191
200
|
async processWakeRequest(request, remotePeerId) {
|
|
192
201
|
// The injected membership predicate is the whole v1 authorization (CadreNode
|
|
@@ -200,15 +209,25 @@ export class StrandWakeService {
|
|
|
200
209
|
log('Rejecting wake for unknown/unparticipated strand %s', request.strandId);
|
|
201
210
|
return { accepted: false, reason: 'Strand not found or not participated in' };
|
|
202
211
|
}
|
|
203
|
-
|
|
212
|
+
// Read before the wake starts: the wake path mutates the shared instance.
|
|
213
|
+
const status = instance.status;
|
|
214
|
+
if (status === 'hibernating' || status === 'idle') {
|
|
204
215
|
log('Waking strand %s on push from %s (reason=%s)', request.strandId, remotePeerId, request.reason ?? 'unspecified');
|
|
205
|
-
|
|
216
|
+
this.startWake(request.strandId);
|
|
206
217
|
}
|
|
207
218
|
else {
|
|
208
|
-
log('Strand %s already %s; push-wake is a no-op', request.strandId,
|
|
219
|
+
log('Strand %s already %s; push-wake is a no-op', request.strandId, status);
|
|
209
220
|
}
|
|
210
|
-
|
|
211
|
-
|
|
221
|
+
return { accepted: true, status };
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Start a wake without awaiting it — the same fire-and-forget an activity-driven
|
|
225
|
+
* local wake uses (`HibernationManager`), which also coalesces the two.
|
|
226
|
+
*/
|
|
227
|
+
startWake(strandId) {
|
|
228
|
+
void this.options.wake(strandId).catch((err) => {
|
|
229
|
+
log('Push-wake of strand %s failed after it was accepted: %o', strandId, err);
|
|
230
|
+
});
|
|
212
231
|
}
|
|
213
232
|
}
|
|
214
233
|
/**
|
|
@@ -235,15 +254,21 @@ export class StrandWakeService {
|
|
|
235
254
|
* exactly the signaling address this ordering puts first — silently inverting
|
|
236
255
|
* it, with no per-dial sorter override to opt out of. For the same reason this
|
|
237
256
|
* does not use `dialPeerAddrs`, which puts relayed addresses last.
|
|
257
|
+
*
|
|
258
|
+
* NOTE: unlike `dialPeerAddrs`, this does not drop addresses that relay through this node, so a
|
|
259
|
+
* relay waking a peer that holds a reservation on it tries that address and gets `Can not dial
|
|
260
|
+
* self` (fast, then the next candidate). If wakes are ever sent from a relay to its own
|
|
261
|
+
* reservation holders routinely, share `dialPeerAddrs`'s filter here.
|
|
238
262
|
*/
|
|
239
263
|
export async function dialWake(node, addrs, request, options = {}) {
|
|
240
264
|
if (addrs.length === 0) {
|
|
241
265
|
throw new Error('No dialable address for wake target');
|
|
242
266
|
}
|
|
243
267
|
const protocolId = options.protocolId ?? WAKE_PROTOCOL;
|
|
268
|
+
const perAddressMs = options.timeoutMs ?? relayedRequestBudgetMs(options.linkRoundTripMs);
|
|
244
269
|
const budget = {
|
|
245
|
-
perAddressMs
|
|
246
|
-
totalMs: options.budgetMs ??
|
|
270
|
+
perAddressMs,
|
|
271
|
+
totalMs: options.budgetMs ?? WAKE_DIAL_ATTEMPTS * perAddressMs,
|
|
247
272
|
};
|
|
248
273
|
// The attempt's signal aborts the in-flight dialProtocol and resets the live
|
|
249
274
|
// stream, so neither the connect nor the ack-read leaks.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"strand-wake-protocol.js","sourceRoot":"","sources":["../src/strand-wake-protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAsB,
|
|
1
|
+
{"version":3,"file":"strand-wake-protocol.js","sourceRoot":"","sources":["../src/strand-wake-protocol.ts"],"names":[],"mappings":"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"}
|