@replit/river 0.21.0 → 0.22.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.
Files changed (68) hide show
  1. package/README.md +1 -1
  2. package/dist/{chunk-5WFL722S.js → chunk-3MFX6NXA.js} +94 -3
  3. package/dist/chunk-3MFX6NXA.js.map +1 -0
  4. package/dist/{chunk-NFV77C2M.js → chunk-GCLEWC26.js} +340 -507
  5. package/dist/chunk-GCLEWC26.js.map +1 -0
  6. package/dist/chunk-HUBFYN37.js +60 -0
  7. package/dist/chunk-HUBFYN37.js.map +1 -0
  8. package/dist/{chunk-DT5JS6TM.js → chunk-OTQNCLFH.js} +1 -1
  9. package/dist/chunk-OTQNCLFH.js.map +1 -0
  10. package/dist/{chunk-MJR36SUY.js → chunk-S3YKQT4J.js} +2 -2
  11. package/dist/{chunk-QU2EE6YU.js → chunk-ZPBWKBM5.js} +361 -394
  12. package/dist/chunk-ZPBWKBM5.js.map +1 -0
  13. package/dist/{connection-8a71dbe2.d.ts → connection-8b059ac4.d.ts} +6 -4
  14. package/dist/{connection-d49d5d56.d.ts → connection-bbfe1147.d.ts} +1 -1
  15. package/dist/{index-3ac92295.d.ts → index-2ece5234.d.ts} +18 -7
  16. package/dist/logging/index.cjs.map +1 -1
  17. package/dist/logging/index.d.cts +2 -1
  18. package/dist/logging/index.d.ts +2 -1
  19. package/dist/logging/index.js +1 -1
  20. package/dist/router/index.cjs +384 -492
  21. package/dist/router/index.cjs.map +1 -1
  22. package/dist/router/index.d.cts +5 -4
  23. package/dist/router/index.d.ts +5 -4
  24. package/dist/router/index.js +5 -4
  25. package/dist/{services-abc077db.d.ts → services-acbcc441.d.ts} +1 -1
  26. package/dist/{services-8496d6e8.d.ts → services-cb01a7a8.d.ts} +1 -1
  27. package/dist/transport/impls/uds/client.cjs +202 -155
  28. package/dist/transport/impls/uds/client.cjs.map +1 -1
  29. package/dist/transport/impls/uds/client.d.cts +3 -2
  30. package/dist/transport/impls/uds/client.d.ts +3 -2
  31. package/dist/transport/impls/uds/client.js +4 -4
  32. package/dist/transport/impls/uds/server.cjs +295 -264
  33. package/dist/transport/impls/uds/server.cjs.map +1 -1
  34. package/dist/transport/impls/uds/server.d.cts +3 -2
  35. package/dist/transport/impls/uds/server.d.ts +3 -2
  36. package/dist/transport/impls/uds/server.js +4 -4
  37. package/dist/transport/impls/ws/client.cjs +256 -214
  38. package/dist/transport/impls/ws/client.cjs.map +1 -1
  39. package/dist/transport/impls/ws/client.d.cts +6 -6
  40. package/dist/transport/impls/ws/client.d.ts +6 -6
  41. package/dist/transport/impls/ws/client.js +34 -49
  42. package/dist/transport/impls/ws/client.js.map +1 -1
  43. package/dist/transport/impls/ws/server.cjs +317 -278
  44. package/dist/transport/impls/ws/server.cjs.map +1 -1
  45. package/dist/transport/impls/ws/server.d.cts +5 -4
  46. package/dist/transport/impls/ws/server.d.ts +5 -4
  47. package/dist/transport/impls/ws/server.js +4 -4
  48. package/dist/transport/impls/ws/server.js.map +1 -1
  49. package/dist/transport/index.cjs +406 -391
  50. package/dist/transport/index.cjs.map +1 -1
  51. package/dist/transport/index.d.cts +5 -5
  52. package/dist/transport/index.d.ts +5 -5
  53. package/dist/transport/index.js +3 -3
  54. package/dist/util/testHelpers.cjs +71 -19
  55. package/dist/util/testHelpers.cjs.map +1 -1
  56. package/dist/util/testHelpers.d.cts +20 -8
  57. package/dist/util/testHelpers.d.ts +20 -8
  58. package/dist/util/testHelpers.js +13 -12
  59. package/dist/util/testHelpers.js.map +1 -1
  60. package/dist/wslike-e0b32dd5.d.ts +40 -0
  61. package/package.json +4 -5
  62. package/dist/chunk-2ERP6FUE.js +0 -42
  63. package/dist/chunk-2ERP6FUE.js.map +0 -1
  64. package/dist/chunk-5WFL722S.js.map +0 -1
  65. package/dist/chunk-DT5JS6TM.js.map +0 -1
  66. package/dist/chunk-NFV77C2M.js.map +0 -1
  67. package/dist/chunk-QU2EE6YU.js.map +0 -1
  68. /package/dist/{chunk-MJR36SUY.js.map → chunk-S3YKQT4J.js.map} +0 -0
@@ -109,18 +109,70 @@ function isAck(controlFlag) {
109
109
  return (controlFlag & 1 /* AckBit */) === 1 /* AckBit */;
110
110
  }
111
111
 
112
+ // tracing/index.ts
113
+ var import_api = require("@opentelemetry/api");
114
+
115
+ // package.json
116
+ var version = "0.22.0";
117
+
118
+ // tracing/index.ts
119
+ function getPropagationContext(ctx) {
120
+ const tracing = {
121
+ traceparent: "",
122
+ tracestate: ""
123
+ };
124
+ import_api.propagation.inject(ctx, tracing);
125
+ return tracing;
126
+ }
127
+ function createSessionTelemetryInfo(session, propagationCtx) {
128
+ const ctx = propagationCtx ? import_api.propagation.extract(import_api.context.active(), propagationCtx) : import_api.context.active();
129
+ const span = tracer.startSpan(
130
+ `session ${session.id}`,
131
+ {
132
+ attributes: {
133
+ component: "river",
134
+ "river.session.id": session.id,
135
+ "river.session.to": session.to,
136
+ "river.session.from": session.from
137
+ }
138
+ },
139
+ ctx
140
+ );
141
+ return { span, ctx };
142
+ }
143
+ function createConnectionTelemetryInfo(connection, sessionSpan) {
144
+ const ctx = import_api.trace.setSpan(import_api.context.active(), sessionSpan);
145
+ const span = tracer.startSpan(
146
+ `connection ${connection.id}`,
147
+ {
148
+ attributes: {
149
+ component: "river",
150
+ "river.connection.id": connection.id
151
+ },
152
+ links: [{ context: sessionSpan.spanContext() }]
153
+ },
154
+ ctx
155
+ );
156
+ return { span, ctx };
157
+ }
158
+ var tracer = import_api.trace.getTracer("river", version);
159
+ var tracing_default = tracer;
160
+
112
161
  // transport/session.ts
162
+ var import_api2 = require("@opentelemetry/api");
113
163
  var nanoid2 = (0, import_nanoid2.customAlphabet)("1234567890abcdefghijklmnopqrstuvxyz", 6);
114
164
  var unsafeId = () => nanoid2();
115
165
  var Connection = class {
116
- debugId;
166
+ id;
167
+ telemetry;
117
168
  constructor() {
118
- this.debugId = `conn-${unsafeId()}`;
169
+ this.id = `conn-${nanoid2(12)}`;
119
170
  }
120
171
  };
121
172
  var Session = class {
122
173
  codec;
123
174
  options;
175
+ telemetry;
124
176
  /**
125
177
  * The buffer of messages that have been sent but not yet acknowledged.
126
178
  */
@@ -167,7 +219,7 @@ var Session = class {
167
219
  * The interval for sending heartbeats.
168
220
  */
169
221
  heartbeat;
170
- constructor(conn, from, to, options) {
222
+ constructor(conn, from, to, options, propagationCtx) {
171
223
  this.id = `session-${nanoid2(12)}`;
172
224
  this.options = options;
173
225
  this.from = from;
@@ -179,13 +231,14 @@ var Session = class {
179
231
  () => this.sendHeartbeat(),
180
232
  options.heartbeatIntervalMs
181
233
  );
234
+ this.telemetry = createSessionTelemetryInfo(this, propagationCtx);
182
235
  }
183
236
  get loggingMetadata() {
184
237
  return {
185
238
  clientId: this.from,
186
239
  connectedTo: this.to,
187
240
  sessionId: this.id,
188
- connId: this.connection?.debugId
241
+ connId: this.connection?.id
189
242
  };
190
243
  }
191
244
  /**
@@ -230,6 +283,7 @@ var Session = class {
230
283
  `closing connection to ${this.to} due to inactivity (missed ${misses} heartbeats which is ${missDuration}ms)`,
231
284
  this.loggingMetadata
232
285
  );
286
+ this.telemetry.span.addEvent("closing connection due to inactivity");
233
287
  this.closeStaleConnection();
234
288
  }
235
289
  return;
@@ -251,32 +305,38 @@ var Session = class {
251
305
  sendBufferedMessages(conn) {
252
306
  log?.info(`resending ${this.sendBuffer.length} buffered messages`, {
253
307
  ...this.loggingMetadata,
254
- connId: conn.debugId
308
+ connId: conn.id
255
309
  });
256
310
  for (const msg of this.sendBuffer) {
257
311
  log?.debug(`resending msg`, {
258
312
  ...this.loggingMetadata,
259
313
  fullTransportMessage: msg,
260
- connId: conn.debugId
314
+ connId: conn.id
261
315
  });
262
316
  const ok = conn.send(this.codec.toBuffer(msg));
263
317
  if (!ok) {
264
318
  const errMsg = `failed to send buffered message to ${this.to} (sus, this is a fresh connection)`;
319
+ conn.telemetry?.span.setStatus({
320
+ code: import_api2.SpanStatusCode.ERROR,
321
+ message: errMsg
322
+ });
265
323
  log?.error(errMsg, {
266
324
  ...this.loggingMetadata,
267
325
  fullTransportMessage: msg,
268
- connId: conn.debugId
326
+ connId: conn.id,
327
+ tags: ["invariant-violation"]
269
328
  });
270
- throw new Error(errMsg);
329
+ conn.close();
330
+ return;
271
331
  }
272
332
  }
273
333
  }
274
334
  updateBookkeeping(ack, seq) {
275
335
  if (seq + 1 < this.ack) {
276
- log?.error(
277
- `received stale seq ${seq} + 1 < ${this.ack}`,
278
- this.loggingMetadata
279
- );
336
+ log?.error(`received stale seq ${seq} + 1 < ${this.ack}`, {
337
+ ...this.loggingMetadata,
338
+ tags: ["invariant-violation"]
339
+ });
280
340
  return;
281
341
  }
282
342
  this.sendBuffer = this.sendBuffer.filter((unacked) => unacked.seq >= ack);
@@ -446,7 +506,6 @@ var UdsConnection = class extends Connection {
446
506
 
447
507
  // transport/transport.ts
448
508
  var import_value = require("@sinclair/typebox/value");
449
- var import_api2 = require("@opentelemetry/api");
450
509
 
451
510
  // transport/events.ts
452
511
  var ProtocolError = {
@@ -482,11 +541,6 @@ var EventDispatcher = class {
482
541
  }
483
542
  };
484
543
 
485
- // tracing/index.ts
486
- var import_api = require("@opentelemetry/api");
487
- var tracer = import_api.trace.getTracer("river");
488
- var tracing_default = tracer;
489
-
490
544
  // util/stringify.ts
491
545
  function coerceErrorString(err) {
492
546
  if (err instanceof Error) {
@@ -619,6 +673,7 @@ var NaiveJsonCodec = {
619
673
  };
620
674
 
621
675
  // transport/transport.ts
676
+ var import_api3 = require("@opentelemetry/api");
622
677
  var defaultTransportOptions = {
623
678
  heartbeatIntervalMs: 1e3,
624
679
  heartbeatsUntilDead: 2,
@@ -697,17 +752,22 @@ var Transport = class {
697
752
  status: "connect",
698
753
  conn
699
754
  });
755
+ conn.telemetry = createConnectionTelemetryInfo(
756
+ conn,
757
+ session.telemetry.span
758
+ );
700
759
  if (isReconnect) {
701
760
  session.replaceWithNewConnection(conn);
702
761
  log?.info(`reconnected to ${connectedTo}`, session.loggingMetadata);
703
762
  }
704
763
  }
705
- createSession(to, conn) {
764
+ createSession(to, conn, propagationCtx) {
706
765
  const session = new Session(
707
766
  conn,
708
767
  this.clientId,
709
768
  to,
710
- this.options
769
+ this.options,
770
+ propagationCtx
711
771
  );
712
772
  this.sessions.set(session.to, session);
713
773
  this.eventDispatcher.dispatchEvent("sessionStatus", {
@@ -716,11 +776,11 @@ var Transport = class {
716
776
  });
717
777
  return session;
718
778
  }
719
- getOrCreateSession(to, conn, sessionId) {
779
+ getOrCreateSession(to, conn, sessionId, propagationCtx) {
720
780
  let session = this.sessions.get(to);
721
781
  let isReconnect = session !== void 0;
722
782
  if (session?.advertisedSessionId !== void 0 && sessionId !== void 0 && session.advertisedSessionId !== sessionId) {
723
- log?.warn(
783
+ log?.info(
724
784
  `session for ${to} already exists but has a different session id (expected: ${session.advertisedSessionId}, got: ${sessionId}), creating a new one`,
725
785
  session.loggingMetadata
726
786
  );
@@ -729,7 +789,7 @@ var Transport = class {
729
789
  session = void 0;
730
790
  }
731
791
  if (!session) {
732
- session = this.createSession(to, conn);
792
+ session = this.createSession(to, conn, propagationCtx);
733
793
  log?.info(
734
794
  `no session for ${to}, created a new one`,
735
795
  session.loggingMetadata
@@ -742,6 +802,7 @@ var Transport = class {
742
802
  }
743
803
  deleteSession(session) {
744
804
  session.close();
805
+ session.telemetry.span.end();
745
806
  this.sessions.delete(session.to);
746
807
  log?.info(
747
808
  `session ${session.id} disconnect from ${session.to}`,
@@ -758,12 +819,16 @@ var Transport = class {
758
819
  * @param connectedTo The peer we are connected to.
759
820
  */
760
821
  onDisconnect(conn, session) {
822
+ conn.telemetry?.span.end();
761
823
  this.eventDispatcher.dispatchEvent("connectionStatus", {
762
824
  status: "disconnect",
763
825
  conn
764
826
  });
765
827
  session.connection = void 0;
766
- session.beginGrace(() => this.deleteSession(session));
828
+ session.beginGrace(() => {
829
+ session.telemetry.span.addEvent("session grace period expired");
830
+ this.deleteSession(session);
831
+ });
767
832
  }
768
833
  /**
769
834
  * Parses a message from a Uint8Array into a {@link OpaqueTransportMessage}.
@@ -797,9 +862,10 @@ var Transport = class {
797
862
  return;
798
863
  const session = this.sessions.get(msg.from);
799
864
  if (!session) {
800
- log?.error(`(invariant violation) no existing session for ${msg.from}`, {
865
+ log?.error(`no existing session for ${msg.from}`, {
801
866
  clientId: this.clientId,
802
- fullTransportMessage: msg
867
+ fullTransportMessage: msg,
868
+ tags: ["invariant-violation"]
803
869
  });
804
870
  return;
805
871
  }
@@ -818,9 +884,14 @@ var Transport = class {
818
884
  const errMsg = `received out-of-order msg (got seq: ${msg.seq}, wanted seq: ${session.nextExpectedSeq})`;
819
885
  log?.error(`${errMsg}, marking connection as dead`, {
820
886
  clientId: this.clientId,
821
- fullTransportMessage: msg
887
+ fullTransportMessage: msg,
888
+ tags: ["invariant-violation"]
822
889
  });
823
890
  this.protocolError(ProtocolError.MessageOrderingViolated, errMsg);
891
+ session.telemetry.span.setStatus({
892
+ code: import_api3.SpanStatusCode.ERROR,
893
+ message: "message order violated"
894
+ });
824
895
  session.close();
825
896
  }
826
897
  return;
@@ -862,7 +933,8 @@ var Transport = class {
862
933
  const err = "transport is destroyed, cant send";
863
934
  log?.error(err, {
864
935
  clientId: this.clientId,
865
- partialTransportMessage: msg
936
+ partialTransportMessage: msg,
937
+ tags: ["invariant-violation"]
866
938
  });
867
939
  this.protocolError(ProtocolError.UseAfterDestroy, err);
868
940
  return void 0;
@@ -947,7 +1019,7 @@ var ClientTransport = class extends Transport {
947
1019
  if (!session) {
948
1020
  log?.warn(
949
1021
  `connection to ${to} timed out waiting for handshake, closing`,
950
- { clientId: this.clientId, connectedTo: to, connId: conn.debugId }
1022
+ { clientId: this.clientId, connectedTo: to, connId: conn.id }
951
1023
  );
952
1024
  conn.close();
953
1025
  }
@@ -965,6 +1037,10 @@ var ClientTransport = class extends Transport {
965
1037
  conn.addDataListener((data2) => {
966
1038
  const parsed = this.parseMsg(data2);
967
1039
  if (!parsed) {
1040
+ conn.telemetry?.span.setStatus({
1041
+ code: import_api3.SpanStatusCode.ERROR,
1042
+ message: "message parse failure"
1043
+ });
968
1044
  conn.close();
969
1045
  return;
970
1046
  }
@@ -987,6 +1063,10 @@ var ClientTransport = class extends Transport {
987
1063
  }
988
1064
  });
989
1065
  conn.addErrorListener((err) => {
1066
+ conn.telemetry?.span.setStatus({
1067
+ code: import_api3.SpanStatusCode.ERROR,
1068
+ message: "connection error"
1069
+ });
990
1070
  log?.warn(`error in connection to ${to}: ${coerceErrorString(err)}`, {
991
1071
  ...session?.loggingMetadata,
992
1072
  clientId: this.clientId,
@@ -997,6 +1077,10 @@ var ClientTransport = class extends Transport {
997
1077
  receiveHandshakeResponseMessage(data, conn) {
998
1078
  const parsed = this.parseMsg(data);
999
1079
  if (!parsed) {
1080
+ conn.telemetry?.span.setStatus({
1081
+ code: import_api3.SpanStatusCode.ERROR,
1082
+ message: "non-transport message"
1083
+ });
1000
1084
  this.protocolError(
1001
1085
  ProtocolError.HandshakeFailed,
1002
1086
  "received non-transport message"
@@ -1004,6 +1088,10 @@ var ClientTransport = class extends Transport {
1004
1088
  return false;
1005
1089
  }
1006
1090
  if (!import_value.Value.Check(ControlMessageHandshakeResponseSchema, parsed.payload)) {
1091
+ conn.telemetry?.span.setStatus({
1092
+ code: import_api3.SpanStatusCode.ERROR,
1093
+ message: "invalid handshake response"
1094
+ });
1007
1095
  log?.warn(`received invalid handshake resp`, {
1008
1096
  clientId: this.clientId,
1009
1097
  connectedTo: parsed.from,
@@ -1016,7 +1104,11 @@ var ClientTransport = class extends Transport {
1016
1104
  return false;
1017
1105
  }
1018
1106
  if (!parsed.payload.status.ok) {
1019
- log?.warn(`received invalid handshake resp`, {
1107
+ conn.telemetry?.span.setStatus({
1108
+ code: import_api3.SpanStatusCode.ERROR,
1109
+ message: "handshake rejected"
1110
+ });
1111
+ log?.warn(`received handshake rejection`, {
1020
1112
  clientId: this.clientId,
1021
1113
  connectedTo: parsed.from,
1022
1114
  fullTransportMessage: parsed
@@ -1046,142 +1138,94 @@ var ClientTransport = class extends Transport {
1046
1138
  * @param to The client ID of the node to connect to.
1047
1139
  */
1048
1140
  async connect(to) {
1049
- return tracing_default.startActiveSpan(
1050
- "connect",
1051
- {
1052
- attributes: {
1053
- component: "river",
1054
- "span.kind": "client"
1055
- },
1056
- kind: import_api2.SpanKind.CLIENT
1057
- },
1058
- async (span) => {
1059
- try {
1060
- await this.connectAttempt(to);
1061
- } catch (e) {
1062
- if (e instanceof Error) {
1063
- span.recordException(e);
1064
- } else {
1065
- span.recordException(coerceErrorString(e));
1066
- }
1067
- span.setStatus({ code: import_api2.SpanStatusCode.ERROR });
1068
- } finally {
1069
- span.end();
1070
- }
1141
+ const canProceedWithConnection = () => this.state === "open";
1142
+ if (!canProceedWithConnection()) {
1143
+ log?.info(
1144
+ `transport state is no longer open, cancelling attempt to connect to ${to}`,
1145
+ { clientId: this.clientId, connectedTo: to }
1146
+ );
1147
+ return;
1148
+ }
1149
+ let reconnectPromise = this.inflightConnectionPromises.get(to);
1150
+ if (!reconnectPromise) {
1151
+ const budgetConsumed = this.retryBudget.getBudgetConsumed(to);
1152
+ if (!this.retryBudget.hasBudget(to)) {
1153
+ const errMsg = `tried to connect to ${to} but retry budget exceeded (more than ${budgetConsumed} attempts in the last ${this.retryBudget.totalBudgetRestoreTime}ms)`;
1154
+ log?.warn(errMsg, { clientId: this.clientId, connectedTo: to });
1155
+ this.protocolError(ProtocolError.RetriesExceeded, errMsg);
1156
+ return;
1071
1157
  }
1072
- );
1073
- }
1074
- async connectAttempt(to, attempt = 0) {
1075
- const retry = await tracing_default.startActiveSpan(
1076
- "connect",
1077
- {
1078
- attributes: {
1079
- component: "river",
1080
- "river.attempt": attempt,
1081
- "span.kind": "client"
1082
- },
1083
- kind: import_api2.SpanKind.CLIENT
1084
- },
1085
- async (span) => {
1158
+ let sleep = Promise.resolve();
1159
+ const backoffMs = this.retryBudget.getBackoffMs(to);
1160
+ if (backoffMs > 0) {
1161
+ sleep = new Promise((resolve) => setTimeout(resolve, backoffMs));
1162
+ }
1163
+ log?.info(`attempting connection to ${to} (${backoffMs}ms backoff)`, {
1164
+ clientId: this.clientId,
1165
+ connectedTo: to
1166
+ });
1167
+ this.retryBudget.consumeBudget(to);
1168
+ reconnectPromise = tracing_default.startActiveSpan("connect", async (span) => {
1086
1169
  try {
1087
- const canProceedWithConnection = () => this.state === "open";
1170
+ span.addEvent("backoff", { backoffMs });
1171
+ await sleep;
1088
1172
  if (!canProceedWithConnection()) {
1089
- log?.info(
1090
- `transport state is no longer open, cancelling attempt to connect to ${to}`,
1091
- { clientId: this.clientId, connectedTo: to }
1092
- );
1093
- return false;
1173
+ throw new Error("transport state is no longer open");
1094
1174
  }
1095
- let reconnectPromise = this.inflightConnectionPromises.get(to);
1096
- if (!reconnectPromise) {
1097
- const budgetConsumed = this.retryBudget.getBudgetConsumed(to);
1098
- if (!this.retryBudget.hasBudget(to)) {
1099
- const errMsg = `tried to connect to ${to} but retry budget exceeded (more than ${budgetConsumed} attempts in the last ${this.retryBudget.totalBudgetRestoreTime}ms)`;
1100
- log?.warn(errMsg, { clientId: this.clientId, connectedTo: to });
1101
- this.protocolError(ProtocolError.RetriesExceeded, errMsg);
1102
- return false;
1103
- }
1104
- let sleep = Promise.resolve();
1105
- const backoffMs = this.retryBudget.getBackoffMs(to);
1106
- if (backoffMs > 0) {
1107
- sleep = new Promise((resolve) => setTimeout(resolve, backoffMs));
1108
- }
1109
- log?.info(
1110
- `attempting connection to ${to} (${backoffMs}ms backoff)`,
1111
- {
1112
- clientId: this.clientId,
1113
- connectedTo: to
1114
- }
1115
- );
1116
- this.retryBudget.consumeBudget(to);
1117
- reconnectPromise = sleep.then(() => {
1118
- if (!canProceedWithConnection()) {
1119
- throw new Error("transport state is no longer open");
1120
- }
1121
- }).then(() => this.createNewOutgoingConnection(to)).then((conn) => {
1122
- if (!canProceedWithConnection()) {
1123
- log?.info(
1124
- `transport state is no longer open, closing pre-handshake connection to ${to}`,
1125
- {
1126
- clientId: this.clientId,
1127
- connectedTo: to,
1128
- connId: conn.debugId
1129
- }
1130
- );
1131
- conn.close();
1132
- throw new Error("transport state is no longer open");
1133
- }
1134
- return this.sendHandshake(to, conn).then((ok) => {
1135
- if (!ok) {
1136
- conn.close();
1137
- throw new Error("failed to send handshake");
1138
- }
1139
- return conn;
1140
- });
1141
- });
1142
- this.inflightConnectionPromises.set(to, reconnectPromise);
1143
- } else {
1175
+ span.addEvent("connecting");
1176
+ const conn = await this.createNewOutgoingConnection(to);
1177
+ if (!canProceedWithConnection()) {
1144
1178
  log?.info(
1145
- `attempting connection to ${to} (reusing previous attempt)`,
1179
+ `transport state is no longer open, closing pre-handshake connection to ${to}`,
1146
1180
  {
1147
1181
  clientId: this.clientId,
1148
- connectedTo: to
1182
+ connectedTo: to,
1183
+ connId: conn.id
1149
1184
  }
1150
1185
  );
1186
+ conn.close();
1187
+ throw new Error("transport state is no longer open");
1151
1188
  }
1152
- try {
1153
- await reconnectPromise;
1154
- } catch (error) {
1155
- this.inflightConnectionPromises.delete(to);
1156
- const errStr = coerceErrorString(error);
1157
- if (!this.reconnectOnConnectionDrop || !canProceedWithConnection()) {
1158
- log?.warn(`connection to ${to} failed (${errStr})`, {
1159
- clientId: this.clientId,
1160
- connectedTo: to
1161
- });
1162
- } else {
1163
- log?.warn(`connection to ${to} failed (${errStr}), retrying`, {
1164
- clientId: this.clientId,
1165
- connectedTo: to
1166
- });
1167
- return true;
1168
- }
1169
- }
1170
- } catch (e) {
1171
- if (e instanceof Error) {
1172
- span.recordException(e);
1173
- } else {
1174
- span.recordException(coerceErrorString(e));
1189
+ span.addEvent("sending handshake");
1190
+ const ok = await this.sendHandshake(to, conn);
1191
+ if (!ok) {
1192
+ conn.close();
1193
+ throw new Error("failed to send handshake");
1175
1194
  }
1176
- span.setStatus({ code: import_api2.SpanStatusCode.ERROR });
1195
+ return conn;
1196
+ } catch (err) {
1197
+ const errStr = coerceErrorString(err);
1198
+ span.recordException(errStr);
1199
+ span.setStatus({ code: import_api3.SpanStatusCode.ERROR });
1200
+ throw err;
1177
1201
  } finally {
1178
1202
  span.end();
1179
1203
  }
1180
- return false;
1204
+ });
1205
+ this.inflightConnectionPromises.set(to, reconnectPromise);
1206
+ } else {
1207
+ log?.info(`attempting connection to ${to} (reusing previous attempt)`, {
1208
+ clientId: this.clientId,
1209
+ connectedTo: to
1210
+ });
1211
+ }
1212
+ try {
1213
+ await reconnectPromise;
1214
+ } catch (error) {
1215
+ this.inflightConnectionPromises.delete(to);
1216
+ const errStr = coerceErrorString(error);
1217
+ if (!this.reconnectOnConnectionDrop || !canProceedWithConnection()) {
1218
+ log?.warn(`connection to ${to} failed (${errStr})`, {
1219
+ clientId: this.clientId,
1220
+ connectedTo: to
1221
+ });
1222
+ } else {
1223
+ log?.warn(`connection to ${to} failed (${errStr}), retrying`, {
1224
+ clientId: this.clientId,
1225
+ connectedTo: to
1226
+ });
1227
+ return this.connect(to);
1181
1228
  }
1182
- );
1183
- if (retry) {
1184
- return this.connectAttempt(to, attempt + 1);
1185
1229
  }
1186
1230
  }
1187
1231
  deleteSession(session) {
@@ -1189,20 +1233,23 @@ var ClientTransport = class extends Transport {
1189
1233
  super.deleteSession(session);
1190
1234
  }
1191
1235
  async sendHandshake(to, conn) {
1192
- const tracing = { traceparent: "", tracestate: "" };
1193
- import_api2.propagation.inject(import_api2.context.active(), tracing);
1194
1236
  let metadata;
1195
1237
  if (this.options.handshake) {
1196
1238
  metadata = await this.options.handshake.get();
1197
1239
  if (!import_value.Value.Check(this.options.handshake.schema, metadata)) {
1198
1240
  log?.error(`handshake metadata did not match schema`, {
1199
1241
  clientId: this.clientId,
1200
- connectedTo: to
1242
+ connectedTo: to,
1243
+ tags: ["invariant-violation"]
1201
1244
  });
1202
1245
  this.protocolError(
1203
1246
  ProtocolError.HandshakeFailed,
1204
1247
  "handshake metadata did not match schema"
1205
1248
  );
1249
+ conn.telemetry?.span.setStatus({
1250
+ code: import_api3.SpanStatusCode.ERROR,
1251
+ message: "handshake meta mismatch"
1252
+ });
1206
1253
  return false;
1207
1254
  }
1208
1255
  }
@@ -1212,7 +1259,7 @@ var ClientTransport = class extends Transport {
1212
1259
  to,
1213
1260
  session.id,
1214
1261
  metadata,
1215
- tracing
1262
+ getPropagationContext(session.telemetry.ctx)
1216
1263
  );
1217
1264
  log?.debug(`sending handshake request to ${to}`, {
1218
1265
  clientId: this.clientId,