@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/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.some((c) => !c.aborted);
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
- public outboundInflightQueue: Pushable<{
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 || !this.started) break; // do not 'return' – finish loop cleanly
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
- this._outboundPump = pipe(this.outboundInflightQueue, drainOutbound).catch(
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: anySignal([
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) {