@dbcube/core 4.1.11 → 4.1.13
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/index.cjs +146 -29
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +146 -29
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -916,6 +916,8 @@ var net = __toESM(require("net"));
|
|
|
916
916
|
var import_child_process2 = require("child_process");
|
|
917
917
|
var globalTcpServers = /* @__PURE__ */ new Map();
|
|
918
918
|
var globalTcpConnections = /* @__PURE__ */ new Map();
|
|
919
|
+
var connectionQueues = /* @__PURE__ */ new Map();
|
|
920
|
+
var connectionProcessing = /* @__PURE__ */ new Map();
|
|
919
921
|
var queryCache = /* @__PURE__ */ new Map();
|
|
920
922
|
var cacheSize = 0;
|
|
921
923
|
var MAX_CACHE_SIZE = 500;
|
|
@@ -1028,41 +1030,49 @@ var QueryEngine = class {
|
|
|
1028
1030
|
return this.config;
|
|
1029
1031
|
}
|
|
1030
1032
|
async run(binary, args) {
|
|
1033
|
+
const isQueryEngine = binary === "query_engine";
|
|
1034
|
+
const isSchemaEngine = binary === "schema_engine";
|
|
1031
1035
|
const actionIndex = args.findIndex((arg) => arg === "--action");
|
|
1032
|
-
const
|
|
1033
|
-
|
|
1034
|
-
|
|
1036
|
+
const action = actionIndex !== -1 ? args[actionIndex + 1] : "";
|
|
1037
|
+
const isExecuteAction = action === "execute";
|
|
1038
|
+
if (isQueryEngine && isExecuteAction || isSchemaEngine) {
|
|
1039
|
+
return this.executeWithTcpServer(args, binary);
|
|
1035
1040
|
} else {
|
|
1036
1041
|
return this.createProcess(binary, args);
|
|
1037
1042
|
}
|
|
1038
1043
|
}
|
|
1039
|
-
async executeWithTcpServer(args) {
|
|
1040
|
-
const
|
|
1044
|
+
async executeWithTcpServer(args, binary = "query_engine") {
|
|
1045
|
+
const serverConnectionId = `${this.connectionId}_${binary}`;
|
|
1046
|
+
const serverInfo = globalTcpServers.get(serverConnectionId);
|
|
1041
1047
|
if (!serverInfo || !serverInfo.process || serverInfo.process.killed) {
|
|
1042
|
-
await this.startTcpServer();
|
|
1043
|
-
await this.waitForServerReady();
|
|
1048
|
+
await this.startTcpServer(binary, serverConnectionId);
|
|
1049
|
+
await this.waitForServerReady(serverConnectionId);
|
|
1044
1050
|
}
|
|
1045
|
-
return this.sendTcpRequestFast(args);
|
|
1051
|
+
return this.sendTcpRequestFast(args, serverConnectionId);
|
|
1046
1052
|
}
|
|
1047
|
-
async waitForServerReady() {
|
|
1053
|
+
async waitForServerReady(serverConnectionId) {
|
|
1048
1054
|
const maxRetries = 10;
|
|
1049
1055
|
const retryDelay = 500;
|
|
1056
|
+
const serverInfo = globalTcpServers.get(serverConnectionId);
|
|
1057
|
+
if (!serverInfo) {
|
|
1058
|
+
throw new Error("Server not found");
|
|
1059
|
+
}
|
|
1050
1060
|
for (let i = 0; i < maxRetries; i++) {
|
|
1051
|
-
if (await this.isServerResponding()) {
|
|
1061
|
+
if (await this.isServerResponding(serverInfo.port)) {
|
|
1052
1062
|
return;
|
|
1053
1063
|
}
|
|
1054
1064
|
await this.sleep(retryDelay);
|
|
1055
1065
|
}
|
|
1056
1066
|
throw new Error("TCP server failed to become ready within timeout");
|
|
1057
1067
|
}
|
|
1058
|
-
async isServerResponding() {
|
|
1068
|
+
async isServerResponding(port) {
|
|
1059
1069
|
return new Promise((resolve5) => {
|
|
1060
1070
|
const client = new net.Socket();
|
|
1061
1071
|
const timeout = setTimeout(() => {
|
|
1062
1072
|
client.destroy();
|
|
1063
1073
|
resolve5(false);
|
|
1064
1074
|
}, 1e3);
|
|
1065
|
-
client.connect(
|
|
1075
|
+
client.connect(port, "127.0.0.1", () => {
|
|
1066
1076
|
clearTimeout(timeout);
|
|
1067
1077
|
client.destroy();
|
|
1068
1078
|
resolve5(true);
|
|
@@ -1087,15 +1097,16 @@ var QueryEngine = class {
|
|
|
1087
1097
|
}
|
|
1088
1098
|
return parsed;
|
|
1089
1099
|
}
|
|
1090
|
-
async startTcpServer() {
|
|
1100
|
+
async startTcpServer(binary, serverConnectionId) {
|
|
1091
1101
|
await this.initializeBinary();
|
|
1092
1102
|
if (!this.binary) {
|
|
1093
1103
|
throw new Error("Binary not initialized");
|
|
1094
1104
|
}
|
|
1095
|
-
|
|
1105
|
+
const basePort = binary === "schema_engine" ? 9900 : 9944;
|
|
1106
|
+
const tcpPort = await this.findAvailablePort(basePort);
|
|
1096
1107
|
return new Promise((resolve5, reject) => {
|
|
1097
|
-
const serverArgs = [...this.arguments, "--action", "server", "--tcp-port",
|
|
1098
|
-
const serverProcess = (0, import_child_process2.spawn)(this.binary[
|
|
1108
|
+
const serverArgs = [...this.arguments, "--action", "server", "--tcp-port", tcpPort.toString()];
|
|
1109
|
+
const serverProcess = (0, import_child_process2.spawn)(this.binary[binary], serverArgs);
|
|
1099
1110
|
let started = false;
|
|
1100
1111
|
const timeout = setTimeout(() => {
|
|
1101
1112
|
if (!started) {
|
|
@@ -1109,8 +1120,8 @@ var QueryEngine = class {
|
|
|
1109
1120
|
if (!started) {
|
|
1110
1121
|
started = true;
|
|
1111
1122
|
clearTimeout(timeout);
|
|
1112
|
-
globalTcpServers.set(
|
|
1113
|
-
port:
|
|
1123
|
+
globalTcpServers.set(serverConnectionId, {
|
|
1124
|
+
port: tcpPort,
|
|
1114
1125
|
process: serverProcess
|
|
1115
1126
|
});
|
|
1116
1127
|
resolve5();
|
|
@@ -1118,10 +1129,10 @@ var QueryEngine = class {
|
|
|
1118
1129
|
}
|
|
1119
1130
|
});
|
|
1120
1131
|
serverProcess.stderr.on("data", (data) => {
|
|
1121
|
-
console.error(`[TCP Server Error] ${data.toString().trim()}`);
|
|
1132
|
+
console.error(`[${binary} TCP Server Error] ${data.toString().trim()}`);
|
|
1122
1133
|
});
|
|
1123
1134
|
serverProcess.on("close", (code) => {
|
|
1124
|
-
globalTcpServers.delete(
|
|
1135
|
+
globalTcpServers.delete(serverConnectionId);
|
|
1125
1136
|
});
|
|
1126
1137
|
serverProcess.on("error", (error) => {
|
|
1127
1138
|
if (!started) {
|
|
@@ -1197,17 +1208,123 @@ var QueryEngine = class {
|
|
|
1197
1208
|
});
|
|
1198
1209
|
});
|
|
1199
1210
|
}
|
|
1200
|
-
async sendTcpRequestFast(args) {
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1211
|
+
async sendTcpRequestFast(args, serverConnectionId) {
|
|
1212
|
+
return new Promise((resolve5, reject) => {
|
|
1213
|
+
let queue = connectionQueues.get(serverConnectionId);
|
|
1214
|
+
if (!queue) {
|
|
1215
|
+
queue = [];
|
|
1216
|
+
connectionQueues.set(serverConnectionId, queue);
|
|
1217
|
+
}
|
|
1218
|
+
queue.push({ args, resolve: resolve5, reject });
|
|
1219
|
+
this.processQueue(serverConnectionId);
|
|
1220
|
+
});
|
|
1221
|
+
}
|
|
1222
|
+
async processQueue(serverConnectionId) {
|
|
1223
|
+
if (connectionProcessing.get(serverConnectionId)) {
|
|
1224
|
+
return;
|
|
1225
|
+
}
|
|
1226
|
+
const queue = connectionQueues.get(serverConnectionId);
|
|
1227
|
+
if (!queue || queue.length === 0) {
|
|
1228
|
+
return;
|
|
1229
|
+
}
|
|
1230
|
+
connectionProcessing.set(serverConnectionId, true);
|
|
1231
|
+
try {
|
|
1232
|
+
const serverInfo = globalTcpServers.get(serverConnectionId);
|
|
1233
|
+
if (!serverInfo) {
|
|
1234
|
+
throw new Error("Server not initialized");
|
|
1235
|
+
}
|
|
1236
|
+
while (queue.length > 0) {
|
|
1237
|
+
const request = queue.shift();
|
|
1238
|
+
if (!request) break;
|
|
1239
|
+
try {
|
|
1240
|
+
let connection = globalTcpConnections.get(serverConnectionId);
|
|
1241
|
+
if (!connection || connection.destroyed || connection.readyState !== "open") {
|
|
1242
|
+
connection = await this.createNewConnection(serverInfo.port);
|
|
1243
|
+
globalTcpConnections.set(serverConnectionId, connection);
|
|
1244
|
+
}
|
|
1245
|
+
const result = await this.executeOnConnection(connection, request.args);
|
|
1246
|
+
request.resolve(result);
|
|
1247
|
+
} catch (error) {
|
|
1248
|
+
globalTcpConnections.delete(serverConnectionId);
|
|
1249
|
+
request.reject(error);
|
|
1250
|
+
}
|
|
1208
1251
|
}
|
|
1252
|
+
} finally {
|
|
1253
|
+
connectionProcessing.set(serverConnectionId, false);
|
|
1209
1254
|
}
|
|
1210
|
-
|
|
1255
|
+
}
|
|
1256
|
+
async createNewConnection(port) {
|
|
1257
|
+
return new Promise((resolve5, reject) => {
|
|
1258
|
+
const client = new net.Socket();
|
|
1259
|
+
client.setNoDelay(true);
|
|
1260
|
+
client.setKeepAlive(true, 6e4);
|
|
1261
|
+
const timeout = setTimeout(() => {
|
|
1262
|
+
client.destroy();
|
|
1263
|
+
reject(new Error("Connection timeout"));
|
|
1264
|
+
}, 5e3);
|
|
1265
|
+
client.connect(port, "127.0.0.1", () => {
|
|
1266
|
+
clearTimeout(timeout);
|
|
1267
|
+
resolve5(client);
|
|
1268
|
+
});
|
|
1269
|
+
client.on("error", (error) => {
|
|
1270
|
+
clearTimeout(timeout);
|
|
1271
|
+
reject(error);
|
|
1272
|
+
});
|
|
1273
|
+
});
|
|
1274
|
+
}
|
|
1275
|
+
async executeOnConnection(connection, args) {
|
|
1276
|
+
return new Promise((resolve5, reject) => {
|
|
1277
|
+
const command = {};
|
|
1278
|
+
for (let i = 0; i < args.length; i += 2) {
|
|
1279
|
+
if (args[i].startsWith("--")) {
|
|
1280
|
+
const key = args[i].substring(2);
|
|
1281
|
+
const value = args[i + 1];
|
|
1282
|
+
command[key] = value;
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
let responseBuffer = "";
|
|
1286
|
+
let isResolved = false;
|
|
1287
|
+
const timeout = setTimeout(() => {
|
|
1288
|
+
if (!isResolved) {
|
|
1289
|
+
isResolved = true;
|
|
1290
|
+
connection.removeListener("data", onData);
|
|
1291
|
+
connection.removeListener("error", onError);
|
|
1292
|
+
reject(new Error("Request timeout"));
|
|
1293
|
+
}
|
|
1294
|
+
}, this.timeout);
|
|
1295
|
+
const onData = (data) => {
|
|
1296
|
+
responseBuffer += data.toString();
|
|
1297
|
+
const match = responseBuffer.match(/PROCESS_RESPONSE:(\{.*\})/);
|
|
1298
|
+
if (match && !isResolved) {
|
|
1299
|
+
isResolved = true;
|
|
1300
|
+
clearTimeout(timeout);
|
|
1301
|
+
connection.removeListener("data", onData);
|
|
1302
|
+
connection.removeListener("error", onError);
|
|
1303
|
+
try {
|
|
1304
|
+
const response = JSON.parse(match[1]);
|
|
1305
|
+
resolve5({
|
|
1306
|
+
status: response.status,
|
|
1307
|
+
message: response.message,
|
|
1308
|
+
data: response.data
|
|
1309
|
+
});
|
|
1310
|
+
} catch (error) {
|
|
1311
|
+
reject(new Error("Failed to parse response"));
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
};
|
|
1315
|
+
const onError = (error) => {
|
|
1316
|
+
if (!isResolved) {
|
|
1317
|
+
isResolved = true;
|
|
1318
|
+
clearTimeout(timeout);
|
|
1319
|
+
connection.removeListener("data", onData);
|
|
1320
|
+
connection.removeListener("error", onError);
|
|
1321
|
+
reject(error);
|
|
1322
|
+
}
|
|
1323
|
+
};
|
|
1324
|
+
connection.on("data", onData);
|
|
1325
|
+
connection.on("error", onError);
|
|
1326
|
+
connection.write(JSON.stringify(command));
|
|
1327
|
+
});
|
|
1211
1328
|
}
|
|
1212
1329
|
async sendOnExistingConnection(connection, args) {
|
|
1213
1330
|
return new Promise((resolve5, reject) => {
|