@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.
- package/README.md +1 -1
- package/dist/{chunk-5WFL722S.js → chunk-3MFX6NXA.js} +94 -3
- package/dist/chunk-3MFX6NXA.js.map +1 -0
- package/dist/{chunk-NFV77C2M.js → chunk-GCLEWC26.js} +340 -507
- package/dist/chunk-GCLEWC26.js.map +1 -0
- package/dist/chunk-HUBFYN37.js +60 -0
- package/dist/chunk-HUBFYN37.js.map +1 -0
- package/dist/{chunk-DT5JS6TM.js → chunk-OTQNCLFH.js} +1 -1
- package/dist/chunk-OTQNCLFH.js.map +1 -0
- package/dist/{chunk-MJR36SUY.js → chunk-S3YKQT4J.js} +2 -2
- package/dist/{chunk-QU2EE6YU.js → chunk-ZPBWKBM5.js} +361 -394
- package/dist/chunk-ZPBWKBM5.js.map +1 -0
- package/dist/{connection-8a71dbe2.d.ts → connection-8b059ac4.d.ts} +6 -4
- package/dist/{connection-d49d5d56.d.ts → connection-bbfe1147.d.ts} +1 -1
- package/dist/{index-3ac92295.d.ts → index-2ece5234.d.ts} +18 -7
- package/dist/logging/index.cjs.map +1 -1
- package/dist/logging/index.d.cts +2 -1
- package/dist/logging/index.d.ts +2 -1
- package/dist/logging/index.js +1 -1
- package/dist/router/index.cjs +384 -492
- package/dist/router/index.cjs.map +1 -1
- package/dist/router/index.d.cts +5 -4
- package/dist/router/index.d.ts +5 -4
- package/dist/router/index.js +5 -4
- package/dist/{services-abc077db.d.ts → services-acbcc441.d.ts} +1 -1
- package/dist/{services-8496d6e8.d.ts → services-cb01a7a8.d.ts} +1 -1
- package/dist/transport/impls/uds/client.cjs +202 -155
- package/dist/transport/impls/uds/client.cjs.map +1 -1
- package/dist/transport/impls/uds/client.d.cts +3 -2
- package/dist/transport/impls/uds/client.d.ts +3 -2
- package/dist/transport/impls/uds/client.js +4 -4
- package/dist/transport/impls/uds/server.cjs +295 -264
- package/dist/transport/impls/uds/server.cjs.map +1 -1
- package/dist/transport/impls/uds/server.d.cts +3 -2
- package/dist/transport/impls/uds/server.d.ts +3 -2
- package/dist/transport/impls/uds/server.js +4 -4
- package/dist/transport/impls/ws/client.cjs +256 -214
- package/dist/transport/impls/ws/client.cjs.map +1 -1
- package/dist/transport/impls/ws/client.d.cts +6 -6
- package/dist/transport/impls/ws/client.d.ts +6 -6
- package/dist/transport/impls/ws/client.js +34 -49
- package/dist/transport/impls/ws/client.js.map +1 -1
- package/dist/transport/impls/ws/server.cjs +317 -278
- package/dist/transport/impls/ws/server.cjs.map +1 -1
- package/dist/transport/impls/ws/server.d.cts +5 -4
- package/dist/transport/impls/ws/server.d.ts +5 -4
- package/dist/transport/impls/ws/server.js +4 -4
- package/dist/transport/impls/ws/server.js.map +1 -1
- package/dist/transport/index.cjs +406 -391
- package/dist/transport/index.cjs.map +1 -1
- package/dist/transport/index.d.cts +5 -5
- package/dist/transport/index.d.ts +5 -5
- package/dist/transport/index.js +3 -3
- package/dist/util/testHelpers.cjs +71 -19
- package/dist/util/testHelpers.cjs.map +1 -1
- package/dist/util/testHelpers.d.cts +20 -8
- package/dist/util/testHelpers.d.ts +20 -8
- package/dist/util/testHelpers.js +13 -12
- package/dist/util/testHelpers.js.map +1 -1
- package/dist/wslike-e0b32dd5.d.ts +40 -0
- package/package.json +4 -5
- package/dist/chunk-2ERP6FUE.js +0 -42
- package/dist/chunk-2ERP6FUE.js.map +0 -1
- package/dist/chunk-5WFL722S.js.map +0 -1
- package/dist/chunk-DT5JS6TM.js.map +0 -1
- package/dist/chunk-NFV77C2M.js.map +0 -1
- package/dist/chunk-QU2EE6YU.js.map +0 -1
- /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
|
-
|
|
166
|
+
id;
|
|
167
|
+
telemetry;
|
|
117
168
|
constructor() {
|
|
118
|
-
this.
|
|
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?.
|
|
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.
|
|
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.
|
|
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.
|
|
326
|
+
connId: conn.id,
|
|
327
|
+
tags: ["invariant-violation"]
|
|
269
328
|
});
|
|
270
|
-
|
|
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
|
-
|
|
278
|
-
|
|
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?.
|
|
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(() =>
|
|
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(`
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
}
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
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
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
{
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
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
|
-
|
|
1170
|
+
span.addEvent("backoff", { backoffMs });
|
|
1171
|
+
await sleep;
|
|
1088
1172
|
if (!canProceedWithConnection()) {
|
|
1089
|
-
|
|
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
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
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
|
-
`
|
|
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
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1262
|
+
getPropagationContext(session.telemetry.ctx)
|
|
1216
1263
|
);
|
|
1217
1264
|
log?.debug(`sending handshake request to ${to}`, {
|
|
1218
1265
|
clientId: this.clientId,
|