@replit/river 0.19.3 → 0.20.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/dist/{chunk-2Z2NE47H.js → chunk-5WFL722S.js} +15 -2
- package/dist/chunk-5WFL722S.js.map +1 -0
- package/dist/{chunk-LDCCELCJ.js → chunk-HGBAUTIW.js} +2 -2
- package/dist/{chunk-QZD2UTDJ.js → chunk-NYOK5VKK.js} +383 -245
- package/dist/chunk-NYOK5VKK.js.map +1 -0
- package/dist/{chunk-SLYSDRLE.js → chunk-YB5LRYL6.js} +517 -260
- package/dist/chunk-YB5LRYL6.js.map +1 -0
- package/dist/{chunk-YHKIWQOC.js → chunk-ZIWOHAQM.js} +2 -2
- package/dist/{connection-cfec12e6.d.ts → connection-d49d5d56.d.ts} +1 -1
- package/dist/{connection-aa0ea000.d.ts → connection-dba95bc8.d.ts} +1 -1
- package/dist/{index-e2513701.d.ts → index-3ac92295.d.ts} +12 -0
- package/dist/logging/index.d.cts +1 -1
- package/dist/logging/index.d.ts +1 -1
- package/dist/router/index.cjs +514 -257
- package/dist/router/index.cjs.map +1 -1
- package/dist/router/index.d.cts +4 -4
- package/dist/router/index.d.ts +4 -4
- package/dist/router/index.js +2 -2
- package/dist/{services-5fc5712d.d.ts → services-8496d6e8.d.ts} +1 -1
- package/dist/{services-4bba42d8.d.ts → services-abc077db.d.ts} +1 -1
- package/dist/transport/impls/uds/client.cjs +150 -74
- package/dist/transport/impls/uds/client.cjs.map +1 -1
- package/dist/transport/impls/uds/client.d.cts +2 -2
- package/dist/transport/impls/uds/client.d.ts +2 -2
- package/dist/transport/impls/uds/client.js +3 -3
- package/dist/transport/impls/uds/server.cjs +249 -169
- package/dist/transport/impls/uds/server.cjs.map +1 -1
- package/dist/transport/impls/uds/server.d.cts +2 -2
- package/dist/transport/impls/uds/server.d.ts +2 -2
- package/dist/transport/impls/uds/server.js +3 -3
- package/dist/transport/impls/ws/client.cjs +150 -74
- package/dist/transport/impls/ws/client.cjs.map +1 -1
- package/dist/transport/impls/ws/client.d.cts +2 -2
- package/dist/transport/impls/ws/client.d.ts +2 -2
- package/dist/transport/impls/ws/client.js +3 -3
- package/dist/transport/impls/ws/server.cjs +249 -169
- package/dist/transport/impls/ws/server.cjs.map +1 -1
- package/dist/transport/impls/ws/server.d.cts +2 -2
- package/dist/transport/impls/ws/server.d.ts +2 -2
- package/dist/transport/impls/ws/server.js +3 -3
- package/dist/transport/index.cjs +387 -243
- package/dist/transport/index.cjs.map +1 -1
- package/dist/transport/index.d.cts +3 -2
- package/dist/transport/index.d.ts +3 -2
- package/dist/transport/index.js +2 -2
- package/dist/util/testHelpers.cjs +1 -0
- package/dist/util/testHelpers.cjs.map +1 -1
- package/dist/util/testHelpers.d.cts +2 -2
- package/dist/util/testHelpers.d.ts +2 -2
- package/dist/util/testHelpers.js +3 -3
- package/package.json +2 -1
- package/dist/chunk-2Z2NE47H.js.map +0 -1
- package/dist/chunk-QZD2UTDJ.js.map +0 -1
- package/dist/chunk-SLYSDRLE.js.map +0 -1
- /package/dist/{chunk-LDCCELCJ.js.map → chunk-HGBAUTIW.js.map} +0 -0
- /package/dist/{chunk-YHKIWQOC.js.map → chunk-ZIWOHAQM.js.map} +0 -0
package/dist/transport/index.cjs
CHANGED
|
@@ -33,6 +33,7 @@ module.exports = __toCommonJS(transport_exports);
|
|
|
33
33
|
|
|
34
34
|
// transport/transport.ts
|
|
35
35
|
var import_value = require("@sinclair/typebox/value");
|
|
36
|
+
var import_api2 = require("@opentelemetry/api");
|
|
36
37
|
|
|
37
38
|
// transport/message.ts
|
|
38
39
|
var import_typebox = require("@sinclair/typebox");
|
|
@@ -47,6 +48,12 @@ var TransportMessageSchema = (t) => import_typebox.Type.Object({
|
|
|
47
48
|
procedureName: import_typebox.Type.Optional(import_typebox.Type.String()),
|
|
48
49
|
streamId: import_typebox.Type.String(),
|
|
49
50
|
controlFlags: import_typebox.Type.Integer(),
|
|
51
|
+
tracing: import_typebox.Type.Optional(
|
|
52
|
+
import_typebox.Type.Object({
|
|
53
|
+
traceparent: import_typebox.Type.String(),
|
|
54
|
+
tracestate: import_typebox.Type.String()
|
|
55
|
+
})
|
|
56
|
+
),
|
|
50
57
|
payload: t
|
|
51
58
|
});
|
|
52
59
|
var ControlMessageAckSchema = import_typebox.Type.Object({
|
|
@@ -84,7 +91,7 @@ var ControlMessagePayloadSchema = import_typebox.Type.Union([
|
|
|
84
91
|
var OpaqueTransportMessageSchema = TransportMessageSchema(
|
|
85
92
|
import_typebox.Type.Unknown()
|
|
86
93
|
);
|
|
87
|
-
function handshakeRequestMessage(from, to, sessionId, metadata) {
|
|
94
|
+
function handshakeRequestMessage(from, to, sessionId, metadata, tracing) {
|
|
88
95
|
return {
|
|
89
96
|
id: (0, import_nanoid.nanoid)(),
|
|
90
97
|
from,
|
|
@@ -93,6 +100,7 @@ function handshakeRequestMessage(from, to, sessionId, metadata) {
|
|
|
93
100
|
ack: 0,
|
|
94
101
|
streamId: (0, import_nanoid.nanoid)(),
|
|
95
102
|
controlFlags: 0,
|
|
103
|
+
tracing,
|
|
96
104
|
payload: {
|
|
97
105
|
type: "HANDSHAKE_REQ",
|
|
98
106
|
protocolVersion: PROTOCOL_VERSION,
|
|
@@ -395,6 +403,11 @@ var Session = class {
|
|
|
395
403
|
}
|
|
396
404
|
};
|
|
397
405
|
|
|
406
|
+
// tracing/index.ts
|
|
407
|
+
var import_api = require("@opentelemetry/api");
|
|
408
|
+
var tracer = import_api.trace.getTracer("river");
|
|
409
|
+
var tracing_default = tracer;
|
|
410
|
+
|
|
398
411
|
// util/stringify.ts
|
|
399
412
|
function coerceErrorString(err) {
|
|
400
413
|
if (err instanceof Error) {
|
|
@@ -954,82 +967,142 @@ var ClientTransport = class extends Transport {
|
|
|
954
967
|
* @param to The client ID of the node to connect to.
|
|
955
968
|
*/
|
|
956
969
|
async connect(to) {
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
}
|
|
979
|
-
log?.info(`attempting connection to ${to} (${backoffMs}ms backoff)`, {
|
|
980
|
-
clientId: this.clientId,
|
|
981
|
-
connectedTo: to
|
|
982
|
-
});
|
|
983
|
-
this.retryBudget.consumeBudget(to);
|
|
984
|
-
reconnectPromise = sleep.then(() => {
|
|
985
|
-
if (!canProceedWithConnection()) {
|
|
986
|
-
throw new Error("transport state is no longer open");
|
|
970
|
+
return tracing_default.startActiveSpan(
|
|
971
|
+
"connect",
|
|
972
|
+
{
|
|
973
|
+
attributes: {
|
|
974
|
+
component: "river",
|
|
975
|
+
"span.kind": "client"
|
|
976
|
+
},
|
|
977
|
+
kind: import_api2.SpanKind.CLIENT
|
|
978
|
+
},
|
|
979
|
+
async (span) => {
|
|
980
|
+
try {
|
|
981
|
+
await this.connectAttempt(to);
|
|
982
|
+
} catch (e) {
|
|
983
|
+
if (e instanceof Error) {
|
|
984
|
+
span.recordException(e);
|
|
985
|
+
} else {
|
|
986
|
+
span.recordException(coerceErrorString(e));
|
|
987
|
+
}
|
|
988
|
+
span.setStatus({ code: import_api2.SpanStatusCode.ERROR });
|
|
989
|
+
} finally {
|
|
990
|
+
span.end();
|
|
987
991
|
}
|
|
988
|
-
}
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
992
|
+
}
|
|
993
|
+
);
|
|
994
|
+
}
|
|
995
|
+
async connectAttempt(to, attempt = 0) {
|
|
996
|
+
const retry = await tracing_default.startActiveSpan(
|
|
997
|
+
"connect",
|
|
998
|
+
{
|
|
999
|
+
attributes: {
|
|
1000
|
+
component: "river",
|
|
1001
|
+
"river.attempt": attempt,
|
|
1002
|
+
"span.kind": "client"
|
|
1003
|
+
},
|
|
1004
|
+
kind: import_api2.SpanKind.CLIENT
|
|
1005
|
+
},
|
|
1006
|
+
async (span) => {
|
|
1007
|
+
try {
|
|
1008
|
+
const canProceedWithConnection = () => this.state === "open";
|
|
1009
|
+
if (!canProceedWithConnection()) {
|
|
1010
|
+
log?.info(
|
|
1011
|
+
`transport state is no longer open, cancelling attempt to connect to ${to}`,
|
|
1012
|
+
{ clientId: this.clientId, connectedTo: to }
|
|
1013
|
+
);
|
|
1014
|
+
return false;
|
|
1015
|
+
}
|
|
1016
|
+
let reconnectPromise = this.inflightConnectionPromises.get(to);
|
|
1017
|
+
if (!reconnectPromise) {
|
|
1018
|
+
const budgetConsumed = this.retryBudget.getBudgetConsumed(to);
|
|
1019
|
+
if (!this.retryBudget.hasBudget(to)) {
|
|
1020
|
+
const errMsg = `tried to connect to ${to} but retry budget exceeded (more than ${budgetConsumed} attempts in the last ${this.retryBudget.totalBudgetRestoreTime}ms)`;
|
|
1021
|
+
log?.warn(errMsg, { clientId: this.clientId, connectedTo: to });
|
|
1022
|
+
this.protocolError(ProtocolError.RetriesExceeded, errMsg);
|
|
1023
|
+
return false;
|
|
996
1024
|
}
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1025
|
+
let sleep = Promise.resolve();
|
|
1026
|
+
const backoffMs = this.retryBudget.getBackoffMs(to);
|
|
1027
|
+
if (backoffMs > 0) {
|
|
1028
|
+
sleep = new Promise((resolve) => setTimeout(resolve, backoffMs));
|
|
1029
|
+
}
|
|
1030
|
+
log?.info(
|
|
1031
|
+
`attempting connection to ${to} (${backoffMs}ms backoff)`,
|
|
1032
|
+
{
|
|
1033
|
+
clientId: this.clientId,
|
|
1034
|
+
connectedTo: to
|
|
1035
|
+
}
|
|
1036
|
+
);
|
|
1037
|
+
this.retryBudget.consumeBudget(to);
|
|
1038
|
+
reconnectPromise = sleep.then(() => {
|
|
1039
|
+
if (!canProceedWithConnection()) {
|
|
1040
|
+
throw new Error("transport state is no longer open");
|
|
1041
|
+
}
|
|
1042
|
+
}).then(() => this.createNewOutgoingConnection(to)).then((conn) => {
|
|
1043
|
+
if (!canProceedWithConnection()) {
|
|
1044
|
+
log?.info(
|
|
1045
|
+
`transport state is no longer open, closing pre-handshake connection to ${to}`,
|
|
1046
|
+
{
|
|
1047
|
+
clientId: this.clientId,
|
|
1048
|
+
connectedTo: to,
|
|
1049
|
+
connId: conn.debugId
|
|
1050
|
+
}
|
|
1051
|
+
);
|
|
1052
|
+
conn.close();
|
|
1053
|
+
throw new Error("transport state is no longer open");
|
|
1054
|
+
}
|
|
1055
|
+
return this.sendHandshake(to, conn).then((ok) => {
|
|
1056
|
+
if (!ok) {
|
|
1057
|
+
conn.close();
|
|
1058
|
+
throw new Error("failed to send handshake");
|
|
1059
|
+
}
|
|
1060
|
+
return conn;
|
|
1061
|
+
});
|
|
1062
|
+
});
|
|
1063
|
+
this.inflightConnectionPromises.set(to, reconnectPromise);
|
|
1064
|
+
} else {
|
|
1065
|
+
log?.info(
|
|
1066
|
+
`attempting connection to ${to} (reusing previous attempt)`,
|
|
1067
|
+
{
|
|
1068
|
+
clientId: this.clientId,
|
|
1069
|
+
connectedTo: to
|
|
1070
|
+
}
|
|
1071
|
+
);
|
|
1005
1072
|
}
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1073
|
+
try {
|
|
1074
|
+
await reconnectPromise;
|
|
1075
|
+
} catch (error) {
|
|
1076
|
+
this.inflightConnectionPromises.delete(to);
|
|
1077
|
+
const errStr = coerceErrorString(error);
|
|
1078
|
+
if (!this.reconnectOnConnectionDrop || !canProceedWithConnection()) {
|
|
1079
|
+
log?.warn(`connection to ${to} failed (${errStr})`, {
|
|
1080
|
+
clientId: this.clientId,
|
|
1081
|
+
connectedTo: to
|
|
1082
|
+
});
|
|
1083
|
+
} else {
|
|
1084
|
+
log?.warn(`connection to ${to} failed (${errStr}), retrying`, {
|
|
1085
|
+
clientId: this.clientId,
|
|
1086
|
+
connectedTo: to
|
|
1087
|
+
});
|
|
1088
|
+
return true;
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
} catch (e) {
|
|
1092
|
+
if (e instanceof Error) {
|
|
1093
|
+
span.recordException(e);
|
|
1094
|
+
} else {
|
|
1095
|
+
span.recordException(coerceErrorString(e));
|
|
1096
|
+
}
|
|
1097
|
+
span.setStatus({ code: import_api2.SpanStatusCode.ERROR });
|
|
1098
|
+
} finally {
|
|
1099
|
+
span.end();
|
|
1100
|
+
}
|
|
1101
|
+
return false;
|
|
1032
1102
|
}
|
|
1103
|
+
);
|
|
1104
|
+
if (retry) {
|
|
1105
|
+
return this.connectAttempt(to, attempt + 1);
|
|
1033
1106
|
}
|
|
1034
1107
|
}
|
|
1035
1108
|
deleteSession(session) {
|
|
@@ -1037,6 +1110,8 @@ var ClientTransport = class extends Transport {
|
|
|
1037
1110
|
super.deleteSession(session);
|
|
1038
1111
|
}
|
|
1039
1112
|
async sendHandshake(to, conn) {
|
|
1113
|
+
const tracing = { traceparent: "", tracestate: "" };
|
|
1114
|
+
import_api2.propagation.inject(import_api2.context.active(), tracing);
|
|
1040
1115
|
let metadata;
|
|
1041
1116
|
if (this.options.handshake) {
|
|
1042
1117
|
metadata = await this.options.handshake.get();
|
|
@@ -1057,7 +1132,8 @@ var ClientTransport = class extends Transport {
|
|
|
1057
1132
|
this.clientId,
|
|
1058
1133
|
to,
|
|
1059
1134
|
session.id,
|
|
1060
|
-
metadata
|
|
1135
|
+
metadata,
|
|
1136
|
+
tracing
|
|
1061
1137
|
);
|
|
1062
1138
|
log?.debug(`sending handshake request to ${to}`, {
|
|
1063
1139
|
clientId: this.clientId,
|
|
@@ -1088,78 +1164,100 @@ var ServerTransport = class extends Transport {
|
|
|
1088
1164
|
});
|
|
1089
1165
|
}
|
|
1090
1166
|
handleConnection(conn) {
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
);
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
void this.receiveHandshakeRequestMessage(data, conn).then(
|
|
1122
|
-
(maybeSession) => {
|
|
1123
|
-
if (!maybeSession) {
|
|
1167
|
+
tracing_default.startActiveSpan(
|
|
1168
|
+
"handleConnection",
|
|
1169
|
+
{
|
|
1170
|
+
attributes: {
|
|
1171
|
+
component: "river",
|
|
1172
|
+
"span.kind": "server"
|
|
1173
|
+
},
|
|
1174
|
+
kind: import_api2.SpanKind.SERVER
|
|
1175
|
+
},
|
|
1176
|
+
(span) => {
|
|
1177
|
+
if (this.state !== "open")
|
|
1178
|
+
return;
|
|
1179
|
+
log?.info(`new incoming connection`, {
|
|
1180
|
+
clientId: this.clientId,
|
|
1181
|
+
connId: conn.debugId
|
|
1182
|
+
});
|
|
1183
|
+
let session = void 0;
|
|
1184
|
+
const client = () => session?.to ?? "unknown";
|
|
1185
|
+
const handshakeTimeout = setTimeout(() => {
|
|
1186
|
+
if (!session) {
|
|
1187
|
+
log?.warn(
|
|
1188
|
+
`connection to ${client()} timed out waiting for handshake, closing`,
|
|
1189
|
+
{
|
|
1190
|
+
clientId: this.clientId,
|
|
1191
|
+
connectedTo: client(),
|
|
1192
|
+
connId: conn.debugId
|
|
1193
|
+
}
|
|
1194
|
+
);
|
|
1195
|
+
span.setStatus({ code: import_api2.SpanStatusCode.ERROR });
|
|
1196
|
+
span.end();
|
|
1124
1197
|
conn.close();
|
|
1198
|
+
}
|
|
1199
|
+
}, this.options.sessionDisconnectGraceMs);
|
|
1200
|
+
const buffer = [];
|
|
1201
|
+
let receivedHandshakeMessage = false;
|
|
1202
|
+
const handshakeHandler = (data) => {
|
|
1203
|
+
if (receivedHandshakeMessage) {
|
|
1204
|
+
buffer.push(data);
|
|
1125
1205
|
return;
|
|
1126
1206
|
}
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1207
|
+
receivedHandshakeMessage = true;
|
|
1208
|
+
clearTimeout(handshakeTimeout);
|
|
1209
|
+
void this.receiveHandshakeRequestMessage(data, conn).then(
|
|
1210
|
+
(maybeSession) => {
|
|
1211
|
+
if (!maybeSession) {
|
|
1212
|
+
span.setStatus({ code: import_api2.SpanStatusCode.ERROR });
|
|
1213
|
+
span.end();
|
|
1214
|
+
conn.close();
|
|
1215
|
+
return;
|
|
1216
|
+
}
|
|
1217
|
+
session = maybeSession;
|
|
1218
|
+
const dataHandler = (data2) => {
|
|
1219
|
+
const parsed = this.parseMsg(data2);
|
|
1220
|
+
if (!parsed) {
|
|
1221
|
+
conn.close();
|
|
1222
|
+
return;
|
|
1223
|
+
}
|
|
1224
|
+
this.handleMsg(parsed);
|
|
1225
|
+
};
|
|
1226
|
+
conn.removeDataListener(handshakeHandler);
|
|
1227
|
+
conn.addDataListener(dataHandler);
|
|
1228
|
+
for (const data2 of buffer) {
|
|
1229
|
+
dataHandler(data2);
|
|
1230
|
+
}
|
|
1231
|
+
buffer.length = 0;
|
|
1133
1232
|
}
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1233
|
+
);
|
|
1234
|
+
};
|
|
1235
|
+
conn.addDataListener(handshakeHandler);
|
|
1236
|
+
conn.addCloseListener(() => {
|
|
1237
|
+
if (session) {
|
|
1238
|
+
log?.info(`connection to ${client()} disconnected`, {
|
|
1239
|
+
clientId: this.clientId,
|
|
1240
|
+
connId: conn.debugId
|
|
1241
|
+
});
|
|
1242
|
+
this.onDisconnect(conn, session);
|
|
1140
1243
|
}
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
log?.warn(
|
|
1159
|
-
`connection to ${client()} got an error: ${coerceErrorString(err)}`,
|
|
1160
|
-
{ clientId: this.clientId, connId: conn.debugId }
|
|
1161
|
-
);
|
|
1162
|
-
});
|
|
1244
|
+
span.setStatus({ code: import_api2.SpanStatusCode.OK });
|
|
1245
|
+
span.end();
|
|
1246
|
+
});
|
|
1247
|
+
conn.addErrorListener((err) => {
|
|
1248
|
+
if (session) {
|
|
1249
|
+
log?.warn(
|
|
1250
|
+
`connection to ${client()} got an error: ${coerceErrorString(
|
|
1251
|
+
err
|
|
1252
|
+
)}`,
|
|
1253
|
+
{ clientId: this.clientId, connId: conn.debugId }
|
|
1254
|
+
);
|
|
1255
|
+
}
|
|
1256
|
+
span.setStatus({ code: import_api2.SpanStatusCode.ERROR });
|
|
1257
|
+
span.end();
|
|
1258
|
+
});
|
|
1259
|
+
}
|
|
1260
|
+
);
|
|
1163
1261
|
}
|
|
1164
1262
|
async receiveHandshakeRequestMessage(data, conn) {
|
|
1165
1263
|
const parsed = this.parseMsg(data);
|
|
@@ -1170,117 +1268,163 @@ var ServerTransport = class extends Transport {
|
|
|
1170
1268
|
);
|
|
1171
1269
|
return false;
|
|
1172
1270
|
}
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
ok: false,
|
|
1177
|
-
reason
|
|
1178
|
-
});
|
|
1179
|
-
conn.send(this.codec.toBuffer(responseMsg2));
|
|
1180
|
-
const logData = typeof parsed.payload === "object" ? { ...parsed, payload: { ...parsed.payload, metadata: "redacted" } } : { ...parsed };
|
|
1181
|
-
log?.warn(`${reason}: ${JSON.stringify(logData)}`, {
|
|
1182
|
-
clientId: this.clientId,
|
|
1183
|
-
connId: conn.debugId
|
|
1184
|
-
});
|
|
1185
|
-
this.protocolError(
|
|
1186
|
-
ProtocolError.HandshakeFailed,
|
|
1187
|
-
"invalid handshake request"
|
|
1188
|
-
);
|
|
1189
|
-
return false;
|
|
1190
|
-
}
|
|
1191
|
-
const gotVersion = parsed.payload.protocolVersion;
|
|
1192
|
-
if (gotVersion !== PROTOCOL_VERSION) {
|
|
1193
|
-
const reason = `incorrect version (got: ${gotVersion} wanted ${PROTOCOL_VERSION})`;
|
|
1194
|
-
const responseMsg2 = handshakeResponseMessage(this.clientId, parsed.from, {
|
|
1195
|
-
ok: false,
|
|
1196
|
-
reason
|
|
1197
|
-
});
|
|
1198
|
-
conn.send(this.codec.toBuffer(responseMsg2));
|
|
1199
|
-
log?.warn(
|
|
1200
|
-
`received handshake msg with incompatible protocol version (got: ${gotVersion}, expected: ${PROTOCOL_VERSION})`,
|
|
1201
|
-
{ clientId: this.clientId, connId: conn.debugId }
|
|
1202
|
-
);
|
|
1203
|
-
this.protocolError(ProtocolError.HandshakeFailed, reason);
|
|
1204
|
-
return false;
|
|
1271
|
+
let activeContext = import_api2.context.active();
|
|
1272
|
+
if (parsed.tracing) {
|
|
1273
|
+
activeContext = import_api2.propagation.extract(activeContext, parsed.tracing);
|
|
1205
1274
|
}
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
)
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1275
|
+
return tracing_default.startActiveSpan(
|
|
1276
|
+
"receiveHandshakeRequestMessage",
|
|
1277
|
+
{
|
|
1278
|
+
attributes: {
|
|
1279
|
+
component: "river",
|
|
1280
|
+
"span.kind": "server"
|
|
1281
|
+
},
|
|
1282
|
+
kind: import_api2.SpanKind.SERVER
|
|
1283
|
+
},
|
|
1284
|
+
activeContext,
|
|
1285
|
+
async (span) => {
|
|
1286
|
+
if (!import_value.Value.Check(ControlMessageHandshakeRequestSchema, parsed.payload)) {
|
|
1287
|
+
const reason = "received invalid handshake msg";
|
|
1288
|
+
const responseMsg2 = handshakeResponseMessage(
|
|
1289
|
+
this.clientId,
|
|
1290
|
+
parsed.from,
|
|
1291
|
+
{
|
|
1292
|
+
ok: false,
|
|
1293
|
+
reason
|
|
1294
|
+
}
|
|
1295
|
+
);
|
|
1296
|
+
conn.send(this.codec.toBuffer(responseMsg2));
|
|
1297
|
+
const logData = typeof parsed.payload === "object" ? {
|
|
1298
|
+
...parsed,
|
|
1299
|
+
payload: { ...parsed.payload, metadata: "redacted" }
|
|
1300
|
+
} : { ...parsed };
|
|
1301
|
+
log?.warn(`${reason}: ${JSON.stringify(logData)}`, {
|
|
1302
|
+
clientId: this.clientId,
|
|
1303
|
+
connId: conn.debugId
|
|
1304
|
+
});
|
|
1305
|
+
this.protocolError(
|
|
1306
|
+
ProtocolError.HandshakeFailed,
|
|
1307
|
+
"invalid handshake request"
|
|
1308
|
+
);
|
|
1309
|
+
span.setStatus({ code: import_api2.SpanStatusCode.ERROR });
|
|
1310
|
+
span.end();
|
|
1311
|
+
return false;
|
|
1312
|
+
}
|
|
1313
|
+
const gotVersion = parsed.payload.protocolVersion;
|
|
1314
|
+
if (gotVersion !== PROTOCOL_VERSION) {
|
|
1315
|
+
const reason = `incorrect version (got: ${gotVersion} wanted ${PROTOCOL_VERSION})`;
|
|
1316
|
+
const responseMsg2 = handshakeResponseMessage(
|
|
1317
|
+
this.clientId,
|
|
1318
|
+
parsed.from,
|
|
1319
|
+
{
|
|
1320
|
+
ok: false,
|
|
1321
|
+
reason
|
|
1322
|
+
}
|
|
1323
|
+
);
|
|
1324
|
+
conn.send(this.codec.toBuffer(responseMsg2));
|
|
1325
|
+
log?.warn(
|
|
1326
|
+
`received handshake msg with incompatible protocol version (got: ${gotVersion}, expected: ${PROTOCOL_VERSION})`,
|
|
1327
|
+
{ clientId: this.clientId, connId: conn.debugId }
|
|
1328
|
+
);
|
|
1329
|
+
this.protocolError(ProtocolError.HandshakeFailed, reason);
|
|
1330
|
+
span.setStatus({ code: import_api2.SpanStatusCode.ERROR });
|
|
1331
|
+
span.end();
|
|
1332
|
+
return false;
|
|
1333
|
+
}
|
|
1334
|
+
const { session, isReconnect } = this.getOrCreateSession(
|
|
1220
1335
|
parsed.from,
|
|
1221
|
-
|
|
1336
|
+
conn,
|
|
1337
|
+
parsed.payload.sessionId
|
|
1222
1338
|
);
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1339
|
+
let handshakeMetadata;
|
|
1340
|
+
if (this.options.handshake) {
|
|
1341
|
+
if (!import_value.Value.Check(
|
|
1342
|
+
this.options.handshake.requestSchema,
|
|
1343
|
+
parsed.payload.metadata
|
|
1344
|
+
)) {
|
|
1345
|
+
const reason = "received malformed handshake metadata";
|
|
1346
|
+
const responseMsg2 = handshakeResponseMessage(
|
|
1347
|
+
this.clientId,
|
|
1348
|
+
parsed.from,
|
|
1349
|
+
{ ok: false, reason }
|
|
1350
|
+
);
|
|
1351
|
+
conn.send(this.codec.toBuffer(responseMsg2));
|
|
1352
|
+
log?.warn(
|
|
1353
|
+
`received malformed handshake metadata from ${parsed.from}`,
|
|
1354
|
+
{
|
|
1355
|
+
clientId: this.clientId,
|
|
1356
|
+
connId: conn.debugId
|
|
1357
|
+
}
|
|
1358
|
+
);
|
|
1359
|
+
this.protocolError(ProtocolError.HandshakeFailed, reason);
|
|
1360
|
+
this.deleteSession(session);
|
|
1361
|
+
span.setStatus({ code: import_api2.SpanStatusCode.ERROR });
|
|
1362
|
+
span.end();
|
|
1363
|
+
return false;
|
|
1364
|
+
}
|
|
1365
|
+
const parsedMetadata = await this.options.handshake.parse(
|
|
1366
|
+
parsed.payload.metadata,
|
|
1367
|
+
session,
|
|
1368
|
+
isReconnect
|
|
1369
|
+
);
|
|
1370
|
+
if (parsedMetadata === false) {
|
|
1371
|
+
const reason = "rejected by server";
|
|
1372
|
+
const responseMsg2 = handshakeResponseMessage(
|
|
1373
|
+
this.clientId,
|
|
1374
|
+
parsed.from,
|
|
1375
|
+
{ ok: false, reason }
|
|
1376
|
+
);
|
|
1377
|
+
conn.send(this.codec.toBuffer(responseMsg2));
|
|
1378
|
+
log?.warn(`rejected handshake from ${parsed.from}`, {
|
|
1379
|
+
clientId: this.clientId,
|
|
1380
|
+
connId: conn.debugId
|
|
1381
|
+
});
|
|
1382
|
+
this.protocolError(ProtocolError.HandshakeFailed, reason);
|
|
1383
|
+
this.deleteSession(session);
|
|
1384
|
+
span.setStatus({ code: import_api2.SpanStatusCode.ERROR });
|
|
1385
|
+
span.end();
|
|
1386
|
+
return false;
|
|
1387
|
+
}
|
|
1388
|
+
if (!import_value.Value.Check(this.options.handshake.parsedSchema, parsedMetadata)) {
|
|
1389
|
+
const reason = "failed to parse handshake metadata";
|
|
1390
|
+
const responseMsg2 = handshakeResponseMessage(
|
|
1391
|
+
this.clientId,
|
|
1392
|
+
parsed.from,
|
|
1393
|
+
{ ok: false, reason }
|
|
1394
|
+
);
|
|
1395
|
+
conn.send(this.codec.toBuffer(responseMsg2));
|
|
1396
|
+
log?.error(`failed to parse handshake metadata`, {
|
|
1397
|
+
clientId: this.clientId,
|
|
1398
|
+
connId: conn.debugId
|
|
1399
|
+
});
|
|
1400
|
+
this.protocolError(ProtocolError.HandshakeFailed, reason);
|
|
1401
|
+
this.deleteSession(session);
|
|
1402
|
+
span.setStatus({ code: import_api2.SpanStatusCode.ERROR });
|
|
1403
|
+
span.end();
|
|
1404
|
+
return false;
|
|
1405
|
+
}
|
|
1406
|
+
handshakeMetadata = parsedMetadata;
|
|
1407
|
+
}
|
|
1408
|
+
handshakeMetadata ??= {};
|
|
1409
|
+
session.metadata = handshakeMetadata;
|
|
1410
|
+
log?.debug(
|
|
1411
|
+
`handshake from ${parsed.from} ok, responding with handshake success`,
|
|
1412
|
+
{ clientId: this.clientId, connId: conn.debugId }
|
|
1243
1413
|
);
|
|
1244
|
-
|
|
1245
|
-
log?.warn(`rejected handshake from ${parsed.from}`, {
|
|
1246
|
-
clientId: this.clientId,
|
|
1247
|
-
connId: conn.debugId
|
|
1248
|
-
});
|
|
1249
|
-
this.protocolError(ProtocolError.HandshakeFailed, reason);
|
|
1250
|
-
this.deleteSession(session);
|
|
1251
|
-
return false;
|
|
1252
|
-
}
|
|
1253
|
-
if (!import_value.Value.Check(this.options.handshake.parsedSchema, parsedMetadata)) {
|
|
1254
|
-
const reason = "failed to parse handshake metadata";
|
|
1255
|
-
const responseMsg2 = handshakeResponseMessage(
|
|
1414
|
+
const responseMsg = handshakeResponseMessage(
|
|
1256
1415
|
this.clientId,
|
|
1257
1416
|
parsed.from,
|
|
1258
|
-
{
|
|
1417
|
+
{
|
|
1418
|
+
ok: true,
|
|
1419
|
+
sessionId: session.id
|
|
1420
|
+
}
|
|
1259
1421
|
);
|
|
1260
|
-
conn.send(this.codec.toBuffer(
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
});
|
|
1265
|
-
this.protocolError(ProtocolError.HandshakeFailed, reason);
|
|
1266
|
-
this.deleteSession(session);
|
|
1267
|
-
return false;
|
|
1422
|
+
conn.send(this.codec.toBuffer(responseMsg));
|
|
1423
|
+
this.onConnect(conn, parsed.from, session, isReconnect);
|
|
1424
|
+
span.end();
|
|
1425
|
+
return session;
|
|
1268
1426
|
}
|
|
1269
|
-
handshakeMetadata = parsedMetadata;
|
|
1270
|
-
}
|
|
1271
|
-
handshakeMetadata ??= {};
|
|
1272
|
-
session.metadata = handshakeMetadata;
|
|
1273
|
-
log?.debug(
|
|
1274
|
-
`handshake from ${parsed.from} ok, responding with handshake success`,
|
|
1275
|
-
{ clientId: this.clientId, connId: conn.debugId }
|
|
1276
1427
|
);
|
|
1277
|
-
const responseMsg = handshakeResponseMessage(this.clientId, parsed.from, {
|
|
1278
|
-
ok: true,
|
|
1279
|
-
sessionId: session.id
|
|
1280
|
-
});
|
|
1281
|
-
conn.send(this.codec.toBuffer(responseMsg));
|
|
1282
|
-
this.onConnect(conn, parsed.from, session, isReconnect);
|
|
1283
|
-
return session;
|
|
1284
1428
|
}
|
|
1285
1429
|
};
|
|
1286
1430
|
// Annotate the CommonJS export names for ESM import in node:
|