@replit/river 0.21.1 → 0.23.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-FDLAPYCK.js → chunk-DZOATC6M.js} +2 -2
- package/dist/{chunk-JMXO5L2X.js → chunk-MJUFKPBT.js} +354 -398
- package/dist/chunk-MJUFKPBT.js.map +1 -0
- package/dist/{chunk-5WFL722S.js → chunk-PCKHBAVP.js} +94 -3
- package/dist/chunk-PCKHBAVP.js.map +1 -0
- package/dist/{chunk-NCXUFDVL.js → chunk-VOJVLWVX.js} +360 -516
- package/dist/chunk-VOJVLWVX.js.map +1 -0
- package/dist/chunk-ZF2UFTNN.js +60 -0
- package/dist/chunk-ZF2UFTNN.js.map +1 -0
- package/dist/{connection-76c5ed01.d.ts → connection-5685d817.d.ts} +6 -4
- package/dist/{connection-975b25c9.d.ts → connection-7582fb92.d.ts} +1 -1
- package/dist/{index-dfad460e.d.ts → index-a6fe0edd.d.ts} +55 -59
- package/dist/logging/index.d.cts +2 -1
- package/dist/logging/index.d.ts +2 -1
- package/dist/router/index.cjs +405 -502
- package/dist/router/index.cjs.map +1 -1
- package/dist/router/index.d.cts +12 -6
- package/dist/router/index.d.ts +12 -6
- package/dist/router/index.js +4 -3
- package/dist/{services-9c496c6e.d.ts → services-be91b485.d.ts} +21 -52
- package/dist/{services-7b716dcf.d.ts → services-eb9326a1.d.ts} +21 -52
- package/dist/transport/impls/uds/client.cjs +197 -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 +3 -3
- package/dist/transport/impls/uds/server.cjs +280 -266
- 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 +3 -3
- package/dist/transport/impls/ws/client.cjs +251 -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 +33 -48
- package/dist/transport/impls/ws/client.js.map +1 -1
- package/dist/transport/impls/ws/server.cjs +302 -280
- 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 +3 -3
- package/dist/transport/impls/ws/server.js.map +1 -1
- package/dist/transport/index.cjs +400 -396
- package/dist/transport/index.cjs.map +1 -1
- package/dist/transport/index.d.cts +25 -14
- package/dist/transport/index.d.ts +25 -14
- package/dist/transport/index.js +2 -2
- package/dist/util/testHelpers.cjs +59 -14
- package/dist/util/testHelpers.cjs.map +1 -1
- package/dist/util/testHelpers.d.cts +14 -5
- package/dist/util/testHelpers.d.ts +14 -5
- package/dist/util/testHelpers.js +12 -5
- package/dist/util/testHelpers.js.map +1 -1
- package/dist/wslike-e0b32dd5.d.ts +40 -0
- package/package.json +4 -5
- package/dist/chunk-3Y7AB5EB.js +0 -42
- package/dist/chunk-3Y7AB5EB.js.map +0 -1
- package/dist/chunk-5WFL722S.js.map +0 -1
- package/dist/chunk-JMXO5L2X.js.map +0 -1
- package/dist/chunk-NCXUFDVL.js.map +0 -1
- /package/dist/{chunk-FDLAPYCK.js.map → chunk-DZOATC6M.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.23.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
|
*/
|
|
@@ -140,12 +192,6 @@ var Session = class {
|
|
|
140
192
|
* for this session.
|
|
141
193
|
*/
|
|
142
194
|
advertisedSessionId;
|
|
143
|
-
/**
|
|
144
|
-
* The metadata for this session, as parsed from the handshake.
|
|
145
|
-
*
|
|
146
|
-
* Will only ever be populated on the server side.
|
|
147
|
-
*/
|
|
148
|
-
metadata;
|
|
149
195
|
/**
|
|
150
196
|
* Number of messages we've sent along this session (excluding handshake and acks)
|
|
151
197
|
*/
|
|
@@ -167,7 +213,7 @@ var Session = class {
|
|
|
167
213
|
* The interval for sending heartbeats.
|
|
168
214
|
*/
|
|
169
215
|
heartbeat;
|
|
170
|
-
constructor(conn, from, to, options) {
|
|
216
|
+
constructor(conn, from, to, options, propagationCtx) {
|
|
171
217
|
this.id = `session-${nanoid2(12)}`;
|
|
172
218
|
this.options = options;
|
|
173
219
|
this.from = from;
|
|
@@ -179,13 +225,14 @@ var Session = class {
|
|
|
179
225
|
() => this.sendHeartbeat(),
|
|
180
226
|
options.heartbeatIntervalMs
|
|
181
227
|
);
|
|
228
|
+
this.telemetry = createSessionTelemetryInfo(this, propagationCtx);
|
|
182
229
|
}
|
|
183
230
|
get loggingMetadata() {
|
|
184
231
|
return {
|
|
185
232
|
clientId: this.from,
|
|
186
233
|
connectedTo: this.to,
|
|
187
234
|
sessionId: this.id,
|
|
188
|
-
connId: this.connection?.
|
|
235
|
+
connId: this.connection?.id
|
|
189
236
|
};
|
|
190
237
|
}
|
|
191
238
|
/**
|
|
@@ -230,6 +277,7 @@ var Session = class {
|
|
|
230
277
|
`closing connection to ${this.to} due to inactivity (missed ${misses} heartbeats which is ${missDuration}ms)`,
|
|
231
278
|
this.loggingMetadata
|
|
232
279
|
);
|
|
280
|
+
this.telemetry.span.addEvent("closing connection due to inactivity");
|
|
233
281
|
this.closeStaleConnection();
|
|
234
282
|
}
|
|
235
283
|
return;
|
|
@@ -251,21 +299,25 @@ var Session = class {
|
|
|
251
299
|
sendBufferedMessages(conn) {
|
|
252
300
|
log?.info(`resending ${this.sendBuffer.length} buffered messages`, {
|
|
253
301
|
...this.loggingMetadata,
|
|
254
|
-
connId: conn.
|
|
302
|
+
connId: conn.id
|
|
255
303
|
});
|
|
256
304
|
for (const msg of this.sendBuffer) {
|
|
257
305
|
log?.debug(`resending msg`, {
|
|
258
306
|
...this.loggingMetadata,
|
|
259
307
|
fullTransportMessage: msg,
|
|
260
|
-
connId: conn.
|
|
308
|
+
connId: conn.id
|
|
261
309
|
});
|
|
262
310
|
const ok = conn.send(this.codec.toBuffer(msg));
|
|
263
311
|
if (!ok) {
|
|
264
312
|
const errMsg = `failed to send buffered message to ${this.to} (sus, this is a fresh connection)`;
|
|
313
|
+
conn.telemetry?.span.setStatus({
|
|
314
|
+
code: import_api2.SpanStatusCode.ERROR,
|
|
315
|
+
message: errMsg
|
|
316
|
+
});
|
|
265
317
|
log?.error(errMsg, {
|
|
266
318
|
...this.loggingMetadata,
|
|
267
319
|
fullTransportMessage: msg,
|
|
268
|
-
connId: conn.
|
|
320
|
+
connId: conn.id,
|
|
269
321
|
tags: ["invariant-violation"]
|
|
270
322
|
});
|
|
271
323
|
conn.close();
|
|
@@ -448,7 +500,6 @@ var UdsConnection = class extends Connection {
|
|
|
448
500
|
|
|
449
501
|
// transport/transport.ts
|
|
450
502
|
var import_value = require("@sinclair/typebox/value");
|
|
451
|
-
var import_api2 = require("@opentelemetry/api");
|
|
452
503
|
|
|
453
504
|
// transport/events.ts
|
|
454
505
|
var ProtocolError = {
|
|
@@ -484,11 +535,6 @@ var EventDispatcher = class {
|
|
|
484
535
|
}
|
|
485
536
|
};
|
|
486
537
|
|
|
487
|
-
// tracing/index.ts
|
|
488
|
-
var import_api = require("@opentelemetry/api");
|
|
489
|
-
var tracer = import_api.trace.getTracer("river");
|
|
490
|
-
var tracing_default = tracer;
|
|
491
|
-
|
|
492
538
|
// util/stringify.ts
|
|
493
539
|
function coerceErrorString(err) {
|
|
494
540
|
if (err instanceof Error) {
|
|
@@ -621,6 +667,7 @@ var NaiveJsonCodec = {
|
|
|
621
667
|
};
|
|
622
668
|
|
|
623
669
|
// transport/transport.ts
|
|
670
|
+
var import_api3 = require("@opentelemetry/api");
|
|
624
671
|
var defaultTransportOptions = {
|
|
625
672
|
heartbeatIntervalMs: 1e3,
|
|
626
673
|
heartbeatsUntilDead: 2,
|
|
@@ -699,17 +746,22 @@ var Transport = class {
|
|
|
699
746
|
status: "connect",
|
|
700
747
|
conn
|
|
701
748
|
});
|
|
749
|
+
conn.telemetry = createConnectionTelemetryInfo(
|
|
750
|
+
conn,
|
|
751
|
+
session.telemetry.span
|
|
752
|
+
);
|
|
702
753
|
if (isReconnect) {
|
|
703
754
|
session.replaceWithNewConnection(conn);
|
|
704
755
|
log?.info(`reconnected to ${connectedTo}`, session.loggingMetadata);
|
|
705
756
|
}
|
|
706
757
|
}
|
|
707
|
-
createSession(to, conn) {
|
|
758
|
+
createSession(to, conn, propagationCtx) {
|
|
708
759
|
const session = new Session(
|
|
709
760
|
conn,
|
|
710
761
|
this.clientId,
|
|
711
762
|
to,
|
|
712
|
-
this.options
|
|
763
|
+
this.options,
|
|
764
|
+
propagationCtx
|
|
713
765
|
);
|
|
714
766
|
this.sessions.set(session.to, session);
|
|
715
767
|
this.eventDispatcher.dispatchEvent("sessionStatus", {
|
|
@@ -718,11 +770,11 @@ var Transport = class {
|
|
|
718
770
|
});
|
|
719
771
|
return session;
|
|
720
772
|
}
|
|
721
|
-
getOrCreateSession(to, conn, sessionId) {
|
|
773
|
+
getOrCreateSession(to, conn, sessionId, propagationCtx) {
|
|
722
774
|
let session = this.sessions.get(to);
|
|
723
775
|
let isReconnect = session !== void 0;
|
|
724
776
|
if (session?.advertisedSessionId !== void 0 && sessionId !== void 0 && session.advertisedSessionId !== sessionId) {
|
|
725
|
-
log?.
|
|
777
|
+
log?.info(
|
|
726
778
|
`session for ${to} already exists but has a different session id (expected: ${session.advertisedSessionId}, got: ${sessionId}), creating a new one`,
|
|
727
779
|
session.loggingMetadata
|
|
728
780
|
);
|
|
@@ -731,7 +783,7 @@ var Transport = class {
|
|
|
731
783
|
session = void 0;
|
|
732
784
|
}
|
|
733
785
|
if (!session) {
|
|
734
|
-
session = this.createSession(to, conn);
|
|
786
|
+
session = this.createSession(to, conn, propagationCtx);
|
|
735
787
|
log?.info(
|
|
736
788
|
`no session for ${to}, created a new one`,
|
|
737
789
|
session.loggingMetadata
|
|
@@ -744,6 +796,7 @@ var Transport = class {
|
|
|
744
796
|
}
|
|
745
797
|
deleteSession(session) {
|
|
746
798
|
session.close();
|
|
799
|
+
session.telemetry.span.end();
|
|
747
800
|
this.sessions.delete(session.to);
|
|
748
801
|
log?.info(
|
|
749
802
|
`session ${session.id} disconnect from ${session.to}`,
|
|
@@ -760,12 +813,16 @@ var Transport = class {
|
|
|
760
813
|
* @param connectedTo The peer we are connected to.
|
|
761
814
|
*/
|
|
762
815
|
onDisconnect(conn, session) {
|
|
816
|
+
conn.telemetry?.span.end();
|
|
763
817
|
this.eventDispatcher.dispatchEvent("connectionStatus", {
|
|
764
818
|
status: "disconnect",
|
|
765
819
|
conn
|
|
766
820
|
});
|
|
767
821
|
session.connection = void 0;
|
|
768
|
-
session.beginGrace(() =>
|
|
822
|
+
session.beginGrace(() => {
|
|
823
|
+
session.telemetry.span.addEvent("session grace period expired");
|
|
824
|
+
this.deleteSession(session);
|
|
825
|
+
});
|
|
769
826
|
}
|
|
770
827
|
/**
|
|
771
828
|
* Parses a message from a Uint8Array into a {@link OpaqueTransportMessage}.
|
|
@@ -825,6 +882,10 @@ var Transport = class {
|
|
|
825
882
|
tags: ["invariant-violation"]
|
|
826
883
|
});
|
|
827
884
|
this.protocolError(ProtocolError.MessageOrderingViolated, errMsg);
|
|
885
|
+
session.telemetry.span.setStatus({
|
|
886
|
+
code: import_api3.SpanStatusCode.ERROR,
|
|
887
|
+
message: "message order violated"
|
|
888
|
+
});
|
|
828
889
|
session.close();
|
|
829
890
|
}
|
|
830
891
|
return;
|
|
@@ -935,6 +996,10 @@ var ClientTransport = class extends Transport {
|
|
|
935
996
|
* tests or a special case where you don't want to reconnect.
|
|
936
997
|
*/
|
|
937
998
|
reconnectOnConnectionDrop = true;
|
|
999
|
+
/**
|
|
1000
|
+
* Optional handshake options for this client.
|
|
1001
|
+
*/
|
|
1002
|
+
handshakeExtensions;
|
|
938
1003
|
constructor(clientId, providedOptions) {
|
|
939
1004
|
super(clientId, providedOptions);
|
|
940
1005
|
this.options = {
|
|
@@ -944,6 +1009,9 @@ var ClientTransport = class extends Transport {
|
|
|
944
1009
|
this.inflightConnectionPromises = /* @__PURE__ */ new Map();
|
|
945
1010
|
this.retryBudget = new LeakyBucketRateLimit(this.options);
|
|
946
1011
|
}
|
|
1012
|
+
extendHandshake(options) {
|
|
1013
|
+
this.handshakeExtensions = options;
|
|
1014
|
+
}
|
|
947
1015
|
handleConnection(conn, to) {
|
|
948
1016
|
if (this.state !== "open")
|
|
949
1017
|
return;
|
|
@@ -952,7 +1020,7 @@ var ClientTransport = class extends Transport {
|
|
|
952
1020
|
if (!session) {
|
|
953
1021
|
log?.warn(
|
|
954
1022
|
`connection to ${to} timed out waiting for handshake, closing`,
|
|
955
|
-
{ clientId: this.clientId, connectedTo: to, connId: conn.
|
|
1023
|
+
{ clientId: this.clientId, connectedTo: to, connId: conn.id }
|
|
956
1024
|
);
|
|
957
1025
|
conn.close();
|
|
958
1026
|
}
|
|
@@ -970,6 +1038,10 @@ var ClientTransport = class extends Transport {
|
|
|
970
1038
|
conn.addDataListener((data2) => {
|
|
971
1039
|
const parsed = this.parseMsg(data2);
|
|
972
1040
|
if (!parsed) {
|
|
1041
|
+
conn.telemetry?.span.setStatus({
|
|
1042
|
+
code: import_api3.SpanStatusCode.ERROR,
|
|
1043
|
+
message: "message parse failure"
|
|
1044
|
+
});
|
|
973
1045
|
conn.close();
|
|
974
1046
|
return;
|
|
975
1047
|
}
|
|
@@ -992,6 +1064,10 @@ var ClientTransport = class extends Transport {
|
|
|
992
1064
|
}
|
|
993
1065
|
});
|
|
994
1066
|
conn.addErrorListener((err) => {
|
|
1067
|
+
conn.telemetry?.span.setStatus({
|
|
1068
|
+
code: import_api3.SpanStatusCode.ERROR,
|
|
1069
|
+
message: "connection error"
|
|
1070
|
+
});
|
|
995
1071
|
log?.warn(`error in connection to ${to}: ${coerceErrorString(err)}`, {
|
|
996
1072
|
...session?.loggingMetadata,
|
|
997
1073
|
clientId: this.clientId,
|
|
@@ -1002,6 +1078,10 @@ var ClientTransport = class extends Transport {
|
|
|
1002
1078
|
receiveHandshakeResponseMessage(data, conn) {
|
|
1003
1079
|
const parsed = this.parseMsg(data);
|
|
1004
1080
|
if (!parsed) {
|
|
1081
|
+
conn.telemetry?.span.setStatus({
|
|
1082
|
+
code: import_api3.SpanStatusCode.ERROR,
|
|
1083
|
+
message: "non-transport message"
|
|
1084
|
+
});
|
|
1005
1085
|
this.protocolError(
|
|
1006
1086
|
ProtocolError.HandshakeFailed,
|
|
1007
1087
|
"received non-transport message"
|
|
@@ -1009,6 +1089,10 @@ var ClientTransport = class extends Transport {
|
|
|
1009
1089
|
return false;
|
|
1010
1090
|
}
|
|
1011
1091
|
if (!import_value.Value.Check(ControlMessageHandshakeResponseSchema, parsed.payload)) {
|
|
1092
|
+
conn.telemetry?.span.setStatus({
|
|
1093
|
+
code: import_api3.SpanStatusCode.ERROR,
|
|
1094
|
+
message: "invalid handshake response"
|
|
1095
|
+
});
|
|
1012
1096
|
log?.warn(`received invalid handshake resp`, {
|
|
1013
1097
|
clientId: this.clientId,
|
|
1014
1098
|
connectedTo: parsed.from,
|
|
@@ -1021,7 +1105,11 @@ var ClientTransport = class extends Transport {
|
|
|
1021
1105
|
return false;
|
|
1022
1106
|
}
|
|
1023
1107
|
if (!parsed.payload.status.ok) {
|
|
1024
|
-
|
|
1108
|
+
conn.telemetry?.span.setStatus({
|
|
1109
|
+
code: import_api3.SpanStatusCode.ERROR,
|
|
1110
|
+
message: "handshake rejected"
|
|
1111
|
+
});
|
|
1112
|
+
log?.warn(`received handshake rejection`, {
|
|
1025
1113
|
clientId: this.clientId,
|
|
1026
1114
|
connectedTo: parsed.from,
|
|
1027
1115
|
fullTransportMessage: parsed
|
|
@@ -1051,142 +1139,94 @@ var ClientTransport = class extends Transport {
|
|
|
1051
1139
|
* @param to The client ID of the node to connect to.
|
|
1052
1140
|
*/
|
|
1053
1141
|
async connect(to) {
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
}
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
span.recordException(coerceErrorString(e));
|
|
1071
|
-
}
|
|
1072
|
-
span.setStatus({ code: import_api2.SpanStatusCode.ERROR });
|
|
1073
|
-
} finally {
|
|
1074
|
-
span.end();
|
|
1075
|
-
}
|
|
1142
|
+
const canProceedWithConnection = () => this.state === "open";
|
|
1143
|
+
if (!canProceedWithConnection()) {
|
|
1144
|
+
log?.info(
|
|
1145
|
+
`transport state is no longer open, cancelling attempt to connect to ${to}`,
|
|
1146
|
+
{ clientId: this.clientId, connectedTo: to }
|
|
1147
|
+
);
|
|
1148
|
+
return;
|
|
1149
|
+
}
|
|
1150
|
+
let reconnectPromise = this.inflightConnectionPromises.get(to);
|
|
1151
|
+
if (!reconnectPromise) {
|
|
1152
|
+
const budgetConsumed = this.retryBudget.getBudgetConsumed(to);
|
|
1153
|
+
if (!this.retryBudget.hasBudget(to)) {
|
|
1154
|
+
const errMsg = `tried to connect to ${to} but retry budget exceeded (more than ${budgetConsumed} attempts in the last ${this.retryBudget.totalBudgetRestoreTime}ms)`;
|
|
1155
|
+
log?.warn(errMsg, { clientId: this.clientId, connectedTo: to });
|
|
1156
|
+
this.protocolError(ProtocolError.RetriesExceeded, errMsg);
|
|
1157
|
+
return;
|
|
1076
1158
|
}
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
{
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
kind: import_api2.SpanKind.CLIENT
|
|
1089
|
-
},
|
|
1090
|
-
async (span) => {
|
|
1159
|
+
let sleep = Promise.resolve();
|
|
1160
|
+
const backoffMs = this.retryBudget.getBackoffMs(to);
|
|
1161
|
+
if (backoffMs > 0) {
|
|
1162
|
+
sleep = new Promise((resolve) => setTimeout(resolve, backoffMs));
|
|
1163
|
+
}
|
|
1164
|
+
log?.info(`attempting connection to ${to} (${backoffMs}ms backoff)`, {
|
|
1165
|
+
clientId: this.clientId,
|
|
1166
|
+
connectedTo: to
|
|
1167
|
+
});
|
|
1168
|
+
this.retryBudget.consumeBudget(to);
|
|
1169
|
+
reconnectPromise = tracing_default.startActiveSpan("connect", async (span) => {
|
|
1091
1170
|
try {
|
|
1092
|
-
|
|
1171
|
+
span.addEvent("backoff", { backoffMs });
|
|
1172
|
+
await sleep;
|
|
1093
1173
|
if (!canProceedWithConnection()) {
|
|
1094
|
-
|
|
1095
|
-
`transport state is no longer open, cancelling attempt to connect to ${to}`,
|
|
1096
|
-
{ clientId: this.clientId, connectedTo: to }
|
|
1097
|
-
);
|
|
1098
|
-
return false;
|
|
1174
|
+
throw new Error("transport state is no longer open");
|
|
1099
1175
|
}
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
if (!this.retryBudget.hasBudget(to)) {
|
|
1104
|
-
const errMsg = `tried to connect to ${to} but retry budget exceeded (more than ${budgetConsumed} attempts in the last ${this.retryBudget.totalBudgetRestoreTime}ms)`;
|
|
1105
|
-
log?.warn(errMsg, { clientId: this.clientId, connectedTo: to });
|
|
1106
|
-
this.protocolError(ProtocolError.RetriesExceeded, errMsg);
|
|
1107
|
-
return false;
|
|
1108
|
-
}
|
|
1109
|
-
let sleep = Promise.resolve();
|
|
1110
|
-
const backoffMs = this.retryBudget.getBackoffMs(to);
|
|
1111
|
-
if (backoffMs > 0) {
|
|
1112
|
-
sleep = new Promise((resolve) => setTimeout(resolve, backoffMs));
|
|
1113
|
-
}
|
|
1114
|
-
log?.info(
|
|
1115
|
-
`attempting connection to ${to} (${backoffMs}ms backoff)`,
|
|
1116
|
-
{
|
|
1117
|
-
clientId: this.clientId,
|
|
1118
|
-
connectedTo: to
|
|
1119
|
-
}
|
|
1120
|
-
);
|
|
1121
|
-
this.retryBudget.consumeBudget(to);
|
|
1122
|
-
reconnectPromise = sleep.then(() => {
|
|
1123
|
-
if (!canProceedWithConnection()) {
|
|
1124
|
-
throw new Error("transport state is no longer open");
|
|
1125
|
-
}
|
|
1126
|
-
}).then(() => this.createNewOutgoingConnection(to)).then((conn) => {
|
|
1127
|
-
if (!canProceedWithConnection()) {
|
|
1128
|
-
log?.info(
|
|
1129
|
-
`transport state is no longer open, closing pre-handshake connection to ${to}`,
|
|
1130
|
-
{
|
|
1131
|
-
clientId: this.clientId,
|
|
1132
|
-
connectedTo: to,
|
|
1133
|
-
connId: conn.debugId
|
|
1134
|
-
}
|
|
1135
|
-
);
|
|
1136
|
-
conn.close();
|
|
1137
|
-
throw new Error("transport state is no longer open");
|
|
1138
|
-
}
|
|
1139
|
-
return this.sendHandshake(to, conn).then((ok) => {
|
|
1140
|
-
if (!ok) {
|
|
1141
|
-
conn.close();
|
|
1142
|
-
throw new Error("failed to send handshake");
|
|
1143
|
-
}
|
|
1144
|
-
return conn;
|
|
1145
|
-
});
|
|
1146
|
-
});
|
|
1147
|
-
this.inflightConnectionPromises.set(to, reconnectPromise);
|
|
1148
|
-
} else {
|
|
1176
|
+
span.addEvent("connecting");
|
|
1177
|
+
const conn = await this.createNewOutgoingConnection(to);
|
|
1178
|
+
if (!canProceedWithConnection()) {
|
|
1149
1179
|
log?.info(
|
|
1150
|
-
`
|
|
1180
|
+
`transport state is no longer open, closing pre-handshake connection to ${to}`,
|
|
1151
1181
|
{
|
|
1152
1182
|
clientId: this.clientId,
|
|
1153
|
-
connectedTo: to
|
|
1183
|
+
connectedTo: to,
|
|
1184
|
+
connId: conn.id
|
|
1154
1185
|
}
|
|
1155
1186
|
);
|
|
1187
|
+
conn.close();
|
|
1188
|
+
throw new Error("transport state is no longer open");
|
|
1156
1189
|
}
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
if (!this.reconnectOnConnectionDrop || !canProceedWithConnection()) {
|
|
1163
|
-
log?.warn(`connection to ${to} failed (${errStr})`, {
|
|
1164
|
-
clientId: this.clientId,
|
|
1165
|
-
connectedTo: to
|
|
1166
|
-
});
|
|
1167
|
-
} else {
|
|
1168
|
-
log?.warn(`connection to ${to} failed (${errStr}), retrying`, {
|
|
1169
|
-
clientId: this.clientId,
|
|
1170
|
-
connectedTo: to
|
|
1171
|
-
});
|
|
1172
|
-
return true;
|
|
1173
|
-
}
|
|
1174
|
-
}
|
|
1175
|
-
} catch (e) {
|
|
1176
|
-
if (e instanceof Error) {
|
|
1177
|
-
span.recordException(e);
|
|
1178
|
-
} else {
|
|
1179
|
-
span.recordException(coerceErrorString(e));
|
|
1190
|
+
span.addEvent("sending handshake");
|
|
1191
|
+
const ok = await this.sendHandshake(to, conn);
|
|
1192
|
+
if (!ok) {
|
|
1193
|
+
conn.close();
|
|
1194
|
+
throw new Error("failed to send handshake");
|
|
1180
1195
|
}
|
|
1181
|
-
|
|
1196
|
+
return conn;
|
|
1197
|
+
} catch (err) {
|
|
1198
|
+
const errStr = coerceErrorString(err);
|
|
1199
|
+
span.recordException(errStr);
|
|
1200
|
+
span.setStatus({ code: import_api3.SpanStatusCode.ERROR });
|
|
1201
|
+
throw err;
|
|
1182
1202
|
} finally {
|
|
1183
1203
|
span.end();
|
|
1184
1204
|
}
|
|
1185
|
-
|
|
1205
|
+
});
|
|
1206
|
+
this.inflightConnectionPromises.set(to, reconnectPromise);
|
|
1207
|
+
} else {
|
|
1208
|
+
log?.info(`attempting connection to ${to} (reusing previous attempt)`, {
|
|
1209
|
+
clientId: this.clientId,
|
|
1210
|
+
connectedTo: to
|
|
1211
|
+
});
|
|
1212
|
+
}
|
|
1213
|
+
try {
|
|
1214
|
+
await reconnectPromise;
|
|
1215
|
+
} catch (error) {
|
|
1216
|
+
this.inflightConnectionPromises.delete(to);
|
|
1217
|
+
const errStr = coerceErrorString(error);
|
|
1218
|
+
if (!this.reconnectOnConnectionDrop || !canProceedWithConnection()) {
|
|
1219
|
+
log?.warn(`connection to ${to} failed (${errStr})`, {
|
|
1220
|
+
clientId: this.clientId,
|
|
1221
|
+
connectedTo: to
|
|
1222
|
+
});
|
|
1223
|
+
} else {
|
|
1224
|
+
log?.warn(`connection to ${to} failed (${errStr}), retrying`, {
|
|
1225
|
+
clientId: this.clientId,
|
|
1226
|
+
connectedTo: to
|
|
1227
|
+
});
|
|
1228
|
+
return this.connect(to);
|
|
1186
1229
|
}
|
|
1187
|
-
);
|
|
1188
|
-
if (retry) {
|
|
1189
|
-
return this.connectAttempt(to, attempt + 1);
|
|
1190
1230
|
}
|
|
1191
1231
|
}
|
|
1192
1232
|
deleteSession(session) {
|
|
@@ -1194,13 +1234,11 @@ var ClientTransport = class extends Transport {
|
|
|
1194
1234
|
super.deleteSession(session);
|
|
1195
1235
|
}
|
|
1196
1236
|
async sendHandshake(to, conn) {
|
|
1197
|
-
const tracing = { traceparent: "", tracestate: "" };
|
|
1198
|
-
import_api2.propagation.inject(import_api2.context.active(), tracing);
|
|
1199
1237
|
let metadata;
|
|
1200
|
-
if (this.
|
|
1201
|
-
metadata = await this.
|
|
1202
|
-
if (!import_value.Value.Check(this.
|
|
1203
|
-
log?.error(`handshake metadata did not match schema`, {
|
|
1238
|
+
if (this.handshakeExtensions) {
|
|
1239
|
+
metadata = await this.handshakeExtensions.construct();
|
|
1240
|
+
if (!import_value.Value.Check(this.handshakeExtensions.schema, metadata)) {
|
|
1241
|
+
log?.error(`constructed handshake metadata did not match schema`, {
|
|
1204
1242
|
clientId: this.clientId,
|
|
1205
1243
|
connectedTo: to,
|
|
1206
1244
|
tags: ["invariant-violation"]
|
|
@@ -1209,6 +1247,10 @@ var ClientTransport = class extends Transport {
|
|
|
1209
1247
|
ProtocolError.HandshakeFailed,
|
|
1210
1248
|
"handshake metadata did not match schema"
|
|
1211
1249
|
);
|
|
1250
|
+
conn.telemetry?.span.setStatus({
|
|
1251
|
+
code: import_api3.SpanStatusCode.ERROR,
|
|
1252
|
+
message: "handshake meta mismatch"
|
|
1253
|
+
});
|
|
1212
1254
|
return false;
|
|
1213
1255
|
}
|
|
1214
1256
|
}
|
|
@@ -1218,7 +1260,7 @@ var ClientTransport = class extends Transport {
|
|
|
1218
1260
|
to,
|
|
1219
1261
|
session.id,
|
|
1220
1262
|
metadata,
|
|
1221
|
-
|
|
1263
|
+
getPropagationContext(session.telemetry.ctx)
|
|
1222
1264
|
);
|
|
1223
1265
|
log?.debug(`sending handshake request to ${to}`, {
|
|
1224
1266
|
clientId: this.clientId,
|