@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 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 isExecuteAction = actionIndex !== -1 && args[actionIndex + 1] === "execute";
1033
- if (isExecuteAction) {
1034
- return this.executeWithTcpServer(args);
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 serverInfo = globalTcpServers.get(this.connectionId);
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(this.tcpPort, "127.0.0.1", () => {
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
- this.tcpPort = await this.findAvailablePort(this.tcpPort);
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", this.tcpPort.toString()];
1098
- const serverProcess = (0, import_child_process2.spawn)(this.binary["query_engine"], serverArgs);
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(this.connectionId, {
1113
- port: this.tcpPort,
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(this.connectionId);
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
- const existingConnection = globalTcpConnections.get(this.connectionId);
1202
- if (existingConnection && existingConnection.readyState === "open") {
1203
- try {
1204
- return await this.sendOnExistingConnection(existingConnection, args);
1205
- } catch (error) {
1206
- globalTcpConnections.delete(this.connectionId);
1207
- existingConnection.destroy();
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
- return await this.createPersistentConnection(args);
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) => {