@peerbit/stream 4.4.0-780f7ce → 4.4.0-9b0640c
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/index.d.ts +2 -10
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +9 -79
- package/dist/src/index.js.map +1 -1
- package/dist/src/pushable-lanes.d.ts +22 -48
- package/dist/src/pushable-lanes.d.ts.map +1 -1
- package/dist/src/pushable-lanes.js +57 -183
- package/dist/src/pushable-lanes.js.map +1 -1
- package/package.json +7 -7
- package/src/index.ts +11 -108
- package/src/pushable-lanes.ts +116 -285
package/src/index.ts
CHANGED
|
@@ -60,7 +60,6 @@ import type {
|
|
|
60
60
|
} from "@peerbit/stream-interface";
|
|
61
61
|
import { AbortError, TimeoutError, delay } from "@peerbit/time";
|
|
62
62
|
import { abortableSource } from "abortable-iterator";
|
|
63
|
-
import { anySignal } from "any-signal";
|
|
64
63
|
import * as lp from "it-length-prefixed";
|
|
65
64
|
import { pipe } from "it-pipe";
|
|
66
65
|
import { type Pushable, pushable } from "it-pushable";
|
|
@@ -131,8 +130,6 @@ const DEFAULT_PRUNED_CONNNECTIONS_TIMEOUT = 30 * 1000;
|
|
|
131
130
|
|
|
132
131
|
const ROUTE_UPDATE_DELAY_FACTOR = 3e4;
|
|
133
132
|
|
|
134
|
-
const DEFAULT_CREATE_OUTBOUND_STREAM_TIMEOUT = 30_000;
|
|
135
|
-
|
|
136
133
|
const getLaneFromPriority = (priority: number) => {
|
|
137
134
|
if (priority > 0) {
|
|
138
135
|
return 0;
|
|
@@ -265,31 +262,14 @@ export class PeerStreams extends TypedEventEmitter<PeerStreamEvents> {
|
|
|
265
262
|
raw,
|
|
266
263
|
).catch((e: any) => {
|
|
267
264
|
candidate.aborted = true;
|
|
268
|
-
try {
|
|
269
|
-
pushableInst.end(e);
|
|
270
|
-
} catch {}
|
|
271
265
|
logError(e as { message: string } as any);
|
|
272
266
|
});
|
|
273
267
|
this.outboundStreams.push(candidate);
|
|
274
268
|
const origAbort = raw.abort?.bind(raw);
|
|
275
269
|
raw.abort = (err?: any) => {
|
|
276
270
|
candidate.aborted = true;
|
|
277
|
-
try {
|
|
278
|
-
pushableInst.end(err);
|
|
279
|
-
} catch {}
|
|
280
271
|
return origAbort?.(err);
|
|
281
272
|
};
|
|
282
|
-
|
|
283
|
-
const origClose = raw.close?.bind(raw);
|
|
284
|
-
if (origClose) {
|
|
285
|
-
raw.close = (...args: any[]) => {
|
|
286
|
-
candidate.aborted = true;
|
|
287
|
-
try {
|
|
288
|
-
pushableInst.end();
|
|
289
|
-
} catch {}
|
|
290
|
-
return origClose(...args);
|
|
291
|
-
};
|
|
292
|
-
}
|
|
293
273
|
return candidate;
|
|
294
274
|
}
|
|
295
275
|
|
|
@@ -330,7 +310,7 @@ export class PeerStreams extends TypedEventEmitter<PeerStreamEvents> {
|
|
|
330
310
|
* Do we have a connection to write on?
|
|
331
311
|
*/
|
|
332
312
|
get isWritable() {
|
|
333
|
-
return this.outboundStreams.
|
|
313
|
+
return this.outboundStreams.length > 0;
|
|
334
314
|
}
|
|
335
315
|
|
|
336
316
|
get usedBandwidth() {
|
|
@@ -362,12 +342,6 @@ export class PeerStreams extends TypedEventEmitter<PeerStreamEvents> {
|
|
|
362
342
|
let failures: any[] = [];
|
|
363
343
|
const failed: OutboundCandidate[] = [];
|
|
364
344
|
for (const c of this.outboundStreams) {
|
|
365
|
-
if (c.aborted) {
|
|
366
|
-
failures.push(new Error("aborted"));
|
|
367
|
-
failed.push(c);
|
|
368
|
-
continue;
|
|
369
|
-
}
|
|
370
|
-
|
|
371
345
|
try {
|
|
372
346
|
c.pushable.push(
|
|
373
347
|
payload,
|
|
@@ -399,9 +373,6 @@ export class PeerStreams extends TypedEventEmitter<PeerStreamEvents> {
|
|
|
399
373
|
(c) => !failed.includes(c),
|
|
400
374
|
);
|
|
401
375
|
for (const f of failed) {
|
|
402
|
-
try {
|
|
403
|
-
f.pushable.end(new AbortError("Failed write" as any));
|
|
404
|
-
} catch {}
|
|
405
376
|
try {
|
|
406
377
|
f.raw.abort?.(new AbortError("Failed write" as any));
|
|
407
378
|
} catch {}
|
|
@@ -841,7 +812,7 @@ export abstract class DirectStream<
|
|
|
841
812
|
private routeMaxRetentionPeriod: number;
|
|
842
813
|
|
|
843
814
|
// for sequential creation of outbound streams
|
|
844
|
-
|
|
815
|
+
private outboundInflightQueue: Pushable<{
|
|
845
816
|
connection: Connection;
|
|
846
817
|
peerId: PeerId;
|
|
847
818
|
}>;
|
|
@@ -850,7 +821,6 @@ export abstract class DirectStream<
|
|
|
850
821
|
seekTimeout: number;
|
|
851
822
|
closeController: AbortController;
|
|
852
823
|
session: number;
|
|
853
|
-
_outboundPump: ReturnType<typeof pipe> | undefined;
|
|
854
824
|
|
|
855
825
|
private _ackCallbacks: Map<
|
|
856
826
|
string,
|
|
@@ -967,76 +937,16 @@ export abstract class DirectStream<
|
|
|
967
937
|
this.closeController = new AbortController();
|
|
968
938
|
|
|
969
939
|
this.outboundInflightQueue = pushable({ objectMode: true });
|
|
970
|
-
|
|
971
|
-
const drainOutbound = async (
|
|
972
|
-
source: AsyncIterable<{ peerId: PeerId; connection: Connection }>,
|
|
973
|
-
) => {
|
|
940
|
+
pipe(this.outboundInflightQueue, async (source) => {
|
|
974
941
|
for await (const { peerId, connection } of source) {
|
|
975
|
-
if (this.stopping ||
|
|
976
|
-
|
|
977
|
-
// Skip closed/closing connections
|
|
978
|
-
if (connection?.timeline?.close != null) {
|
|
979
|
-
logger.debug(
|
|
980
|
-
"skip outbound stream on closed connection %s",
|
|
981
|
-
connection.remoteAddr?.toString(),
|
|
982
|
-
);
|
|
983
|
-
continue;
|
|
984
|
-
}
|
|
985
|
-
|
|
986
|
-
try {
|
|
987
|
-
// Pass an abort + timeout into your stream open so it cannot hang forever
|
|
988
|
-
const attemptSignal = anySignal([
|
|
989
|
-
this.closeController.signal,
|
|
990
|
-
AbortSignal.timeout(DEFAULT_CREATE_OUTBOUND_STREAM_TIMEOUT), // pick a sensible per-attempt cap
|
|
991
|
-
]);
|
|
992
|
-
try {
|
|
993
|
-
await this.createOutboundStream(peerId, connection, {
|
|
994
|
-
signal: attemptSignal,
|
|
995
|
-
});
|
|
996
|
-
} finally {
|
|
997
|
-
attemptSignal.clear?.();
|
|
998
|
-
}
|
|
999
|
-
} catch (e: any) {
|
|
1000
|
-
// Treat common shutdowny errors as transient – do NOT crash the pump
|
|
1001
|
-
const msg = String(e?.message ?? e);
|
|
1002
|
-
if (
|
|
1003
|
-
e?.code === "ERR_STREAM_RESET" ||
|
|
1004
|
-
/unexpected end of input|ECONNRESET|EPIPE|Muxer closed|Premature close/i.test(
|
|
1005
|
-
msg,
|
|
1006
|
-
)
|
|
1007
|
-
) {
|
|
1008
|
-
logger.debug(
|
|
1009
|
-
"createOutboundStream transient failure (%s): %s",
|
|
1010
|
-
connection?.remoteAddr,
|
|
1011
|
-
msg,
|
|
1012
|
-
);
|
|
1013
|
-
} else {
|
|
1014
|
-
logger.warn(
|
|
1015
|
-
"createOutboundStream failed (%s): %o",
|
|
1016
|
-
connection?.remoteAddr,
|
|
1017
|
-
e,
|
|
1018
|
-
);
|
|
1019
|
-
}
|
|
1020
|
-
// continue to next item
|
|
942
|
+
if (this.stopping || this.started === false) {
|
|
943
|
+
return;
|
|
1021
944
|
}
|
|
945
|
+
await this.createOutboundStream(peerId, connection);
|
|
1022
946
|
}
|
|
1023
|
-
}
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
(e) => {
|
|
1027
|
-
// Only log if we didn't intentionally abort
|
|
1028
|
-
if (!this.closeController.signal.aborted) {
|
|
1029
|
-
logger.error("outbound inflight pipeline crashed: %o", e);
|
|
1030
|
-
// Optional: restart the pump to self-heal
|
|
1031
|
-
this._outboundPump = pipe(
|
|
1032
|
-
this.outboundInflightQueue,
|
|
1033
|
-
drainOutbound,
|
|
1034
|
-
).catch((err) =>
|
|
1035
|
-
logger.error("outbound pump crashed again: %o", err),
|
|
1036
|
-
);
|
|
1037
|
-
}
|
|
1038
|
-
},
|
|
1039
|
-
);
|
|
947
|
+
}).catch((e) => {
|
|
948
|
+
logger.error("outbound inflight queue error: " + e?.toString());
|
|
949
|
+
});
|
|
1040
950
|
|
|
1041
951
|
this.closeController.signal.addEventListener("abort", () => {
|
|
1042
952
|
this.outboundInflightQueue.return();
|
|
@@ -1213,11 +1123,7 @@ export abstract class DirectStream<
|
|
|
1213
1123
|
await this.outboundInflightQueue.push({ peerId, connection });
|
|
1214
1124
|
}
|
|
1215
1125
|
|
|
1216
|
-
protected async createOutboundStream(
|
|
1217
|
-
peerId: PeerId,
|
|
1218
|
-
connection: Connection,
|
|
1219
|
-
opts?: { signal?: AbortSignal },
|
|
1220
|
-
) {
|
|
1126
|
+
protected async createOutboundStream(peerId: PeerId, connection: Connection) {
|
|
1221
1127
|
for (const existingStreams of connection.streams) {
|
|
1222
1128
|
if (
|
|
1223
1129
|
existingStreams.protocol &&
|
|
@@ -1244,10 +1150,7 @@ export abstract class DirectStream<
|
|
|
1244
1150
|
// research whether we can do without this so we can push data without beeing able to send
|
|
1245
1151
|
// more info here https://github.com/libp2p/js-libp2p/issues/2321
|
|
1246
1152
|
negotiateFully: true,
|
|
1247
|
-
signal:
|
|
1248
|
-
this.closeController.signal,
|
|
1249
|
-
...(opts?.signal ? [opts.signal] : []),
|
|
1250
|
-
]),
|
|
1153
|
+
signal: this.closeController.signal,
|
|
1251
1154
|
});
|
|
1252
1155
|
|
|
1253
1156
|
if (stream.protocol == null) {
|