@dbcube/core 4.1.12 → 4.1.14

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;
@@ -932,7 +934,7 @@ var QueryEngine = class {
932
934
  this.config = this.setConfig(name);
933
935
  this.arguments = this.setArguments();
934
936
  this.timeout = timeout;
935
- this.connectionId = `${name}_${this.config.type}_${this.config.config.DATABASE}_${this.config.config.HOST || "localhost"}`;
937
+ this.connectionId = `${name}_query_engine_${this.config.type}_${this.config.config.DATABASE}_${this.config.config.HOST || "localhost"}`;
936
938
  this.tcpPort = this.generatePort();
937
939
  }
938
940
  generatePort() {
@@ -1030,7 +1032,8 @@ var QueryEngine = class {
1030
1032
  async run(binary, args) {
1031
1033
  const actionIndex = args.findIndex((arg) => arg === "--action");
1032
1034
  const isExecuteAction = actionIndex !== -1 && args[actionIndex + 1] === "execute";
1033
- if (isExecuteAction) {
1035
+ const isQueryEngine = binary === "query_engine";
1036
+ if (isQueryEngine && isExecuteAction) {
1034
1037
  return this.executeWithTcpServer(args);
1035
1038
  } else {
1036
1039
  return this.createProcess(binary, args);
@@ -1047,22 +1050,26 @@ var QueryEngine = class {
1047
1050
  async waitForServerReady() {
1048
1051
  const maxRetries = 10;
1049
1052
  const retryDelay = 500;
1053
+ const serverInfo = globalTcpServers.get(this.connectionId);
1054
+ if (!serverInfo) {
1055
+ throw new Error("Server not found");
1056
+ }
1050
1057
  for (let i = 0; i < maxRetries; i++) {
1051
- if (await this.isServerResponding()) {
1058
+ if (await this.isServerResponding(serverInfo.port)) {
1052
1059
  return;
1053
1060
  }
1054
1061
  await this.sleep(retryDelay);
1055
1062
  }
1056
1063
  throw new Error("TCP server failed to become ready within timeout");
1057
1064
  }
1058
- async isServerResponding() {
1065
+ async isServerResponding(port) {
1059
1066
  return new Promise((resolve5) => {
1060
1067
  const client = new net.Socket();
1061
1068
  const timeout = setTimeout(() => {
1062
1069
  client.destroy();
1063
1070
  resolve5(false);
1064
1071
  }, 1e3);
1065
- client.connect(this.tcpPort, "127.0.0.1", () => {
1072
+ client.connect(port, "127.0.0.1", () => {
1066
1073
  clearTimeout(timeout);
1067
1074
  client.destroy();
1068
1075
  resolve5(true);
@@ -1118,7 +1125,7 @@ var QueryEngine = class {
1118
1125
  }
1119
1126
  });
1120
1127
  serverProcess.stderr.on("data", (data) => {
1121
- console.error(`[TCP Server Error] ${data.toString().trim()}`);
1128
+ console.error(`[query_engine TCP Server Error] ${data.toString().trim()}`);
1122
1129
  });
1123
1130
  serverProcess.on("close", (code) => {
1124
1131
  globalTcpServers.delete(this.connectionId);
@@ -1131,92 +1138,88 @@ var QueryEngine = class {
1131
1138
  });
1132
1139
  });
1133
1140
  }
1134
- async sendTcpRequest(args) {
1141
+ async sendTcpRequestFast(args) {
1135
1142
  return new Promise((resolve5, reject) => {
1136
- const client = new net.Socket();
1137
- let responseBuffer = "";
1138
- let isResolved = false;
1139
- const timeout = setTimeout(() => {
1140
- if (!isResolved) {
1141
- isResolved = true;
1142
- client.destroy();
1143
- reject(new Error("TCP request timeout"));
1144
- }
1145
- }, this.timeout * 2);
1146
- client.connect(this.tcpPort, "127.0.0.1", () => {
1147
- const dmlIndex = args.findIndex((arg) => arg === "--dml");
1148
- const dmlJson = dmlIndex !== -1 ? args[dmlIndex + 1] : null;
1149
- if (!dmlJson) {
1150
- if (!isResolved) {
1151
- isResolved = true;
1152
- clearTimeout(timeout);
1153
- client.destroy();
1154
- reject(new Error("No DML found in arguments"));
1155
- }
1156
- return;
1157
- }
1158
- const command = {
1159
- action: "execute",
1160
- dml: dmlJson
1161
- };
1162
- client.write(JSON.stringify(command));
1163
- });
1164
- client.on("data", (data) => {
1165
- responseBuffer += data.toString();
1166
- const match = responseBuffer.match(/PROCESS_RESPONSE:(\{.*\})/);
1167
- if (match && !isResolved) {
1168
- isResolved = true;
1169
- clearTimeout(timeout);
1170
- client.destroy();
1171
- try {
1172
- const response = JSON.parse(match[1]);
1173
- resolve5({
1174
- status: response.status,
1175
- message: response.message,
1176
- data: response.data
1177
- });
1178
- } catch (error) {
1179
- reject(new Error("Failed to parse TCP response"));
1143
+ let queue = connectionQueues.get(this.connectionId);
1144
+ if (!queue) {
1145
+ queue = [];
1146
+ connectionQueues.set(this.connectionId, queue);
1147
+ }
1148
+ queue.push({ args, resolve: resolve5, reject });
1149
+ this.processQueue();
1150
+ });
1151
+ }
1152
+ async processQueue() {
1153
+ if (connectionProcessing.get(this.connectionId)) {
1154
+ return;
1155
+ }
1156
+ const queue = connectionQueues.get(this.connectionId);
1157
+ if (!queue || queue.length === 0) {
1158
+ return;
1159
+ }
1160
+ connectionProcessing.set(this.connectionId, true);
1161
+ try {
1162
+ const serverInfo = globalTcpServers.get(this.connectionId);
1163
+ if (!serverInfo) {
1164
+ throw new Error("Server not initialized");
1165
+ }
1166
+ while (queue.length > 0) {
1167
+ const request = queue.shift();
1168
+ if (!request) break;
1169
+ try {
1170
+ let connection = globalTcpConnections.get(this.connectionId);
1171
+ if (!connection || connection.destroyed || connection.readyState !== "open") {
1172
+ connection = await this.createNewConnection(serverInfo.port);
1173
+ globalTcpConnections.set(this.connectionId, connection);
1180
1174
  }
1175
+ const result = await this.executeOnConnection(connection, request.args);
1176
+ request.resolve(result);
1177
+ } catch (error) {
1178
+ globalTcpConnections.delete(this.connectionId);
1179
+ request.reject(error);
1181
1180
  }
1181
+ }
1182
+ } finally {
1183
+ connectionProcessing.set(this.connectionId, false);
1184
+ }
1185
+ }
1186
+ async createNewConnection(port) {
1187
+ return new Promise((resolve5, reject) => {
1188
+ const client = new net.Socket();
1189
+ client.setNoDelay(true);
1190
+ client.setKeepAlive(true, 6e4);
1191
+ const timeout = setTimeout(() => {
1192
+ client.destroy();
1193
+ reject(new Error("Connection timeout"));
1194
+ }, 5e3);
1195
+ client.connect(port, "127.0.0.1", () => {
1196
+ clearTimeout(timeout);
1197
+ resolve5(client);
1182
1198
  });
1183
1199
  client.on("error", (error) => {
1184
- if (!isResolved) {
1185
- isResolved = true;
1186
- clearTimeout(timeout);
1187
- reject(error);
1188
- }
1189
- });
1190
- client.on("close", () => {
1191
- if (!isResolved) {
1192
- clearTimeout(timeout);
1193
- if (!responseBuffer.includes("PROCESS_RESPONSE:")) {
1194
- reject(new Error("Connection closed without valid response"));
1195
- }
1196
- }
1200
+ clearTimeout(timeout);
1201
+ reject(error);
1197
1202
  });
1198
1203
  });
1199
1204
  }
1200
- async sendTcpRequestFast(args) {
1201
- return await this.sendTcpRequest(args);
1202
- }
1203
- async sendOnExistingConnection(connection, args) {
1205
+ async executeOnConnection(connection, args) {
1204
1206
  return new Promise((resolve5, reject) => {
1205
- const dmlIndex = args.findIndex((arg) => arg === "--dml");
1206
- const dmlJson = dmlIndex !== -1 ? args[dmlIndex + 1] : null;
1207
- if (!dmlJson) {
1208
- reject(new Error("No DML found in arguments"));
1209
- return;
1207
+ const command = {};
1208
+ for (let i = 0; i < args.length; i += 2) {
1209
+ if (args[i].startsWith("--")) {
1210
+ const key = args[i].substring(2);
1211
+ const value = args[i + 1];
1212
+ command[key] = value;
1213
+ }
1210
1214
  }
1211
1215
  let responseBuffer = "";
1212
1216
  let isResolved = false;
1213
1217
  const timeout = setTimeout(() => {
1214
1218
  if (!isResolved) {
1215
1219
  isResolved = true;
1216
- connection.off("data", onData);
1217
- connection.off("error", onError);
1218
- globalTcpConnections.delete(this.connectionId);
1219
- reject(new Error("TCP request timeout"));
1220
+ connection.removeListener("data", onData);
1221
+ connection.removeListener("error", onError);
1222
+ reject(new Error("Request timeout"));
1220
1223
  }
1221
1224
  }, this.timeout);
1222
1225
  const onData = (data) => {
@@ -1225,8 +1228,8 @@ var QueryEngine = class {
1225
1228
  if (match && !isResolved) {
1226
1229
  isResolved = true;
1227
1230
  clearTimeout(timeout);
1228
- connection.off("data", onData);
1229
- connection.off("error", onError);
1231
+ connection.removeListener("data", onData);
1232
+ connection.removeListener("error", onError);
1230
1233
  try {
1231
1234
  const response = JSON.parse(match[1]);
1232
1235
  resolve5({
@@ -1235,7 +1238,7 @@ var QueryEngine = class {
1235
1238
  data: response.data
1236
1239
  });
1237
1240
  } catch (error) {
1238
- reject(new Error("Failed to parse TCP response"));
1241
+ reject(new Error("Failed to parse response"));
1239
1242
  }
1240
1243
  }
1241
1244
  };
@@ -1243,118 +1246,16 @@ var QueryEngine = class {
1243
1246
  if (!isResolved) {
1244
1247
  isResolved = true;
1245
1248
  clearTimeout(timeout);
1246
- connection.off("data", onData);
1247
- connection.off("error", onError);
1249
+ connection.removeListener("data", onData);
1250
+ connection.removeListener("error", onError);
1248
1251
  reject(error);
1249
1252
  }
1250
1253
  };
1251
1254
  connection.on("data", onData);
1252
1255
  connection.on("error", onError);
1253
- const command = {
1254
- action: "execute",
1255
- dml: dmlJson
1256
- };
1257
1256
  connection.write(JSON.stringify(command));
1258
1257
  });
1259
1258
  }
1260
- async createPersistentConnection(args) {
1261
- return new Promise((resolve5, reject) => {
1262
- let client = globalTcpConnections.get(this.connectionId);
1263
- let isNewConnection = false;
1264
- if (!client || client.destroyed) {
1265
- client = new net.Socket();
1266
- isNewConnection = true;
1267
- client.setNoDelay(true);
1268
- client.setKeepAlive(true, 6e4);
1269
- client.setMaxListeners(20);
1270
- }
1271
- let responseBuffer = "";
1272
- let isResolved = false;
1273
- const timeout = setTimeout(() => {
1274
- if (!isResolved) {
1275
- isResolved = true;
1276
- client.removeListener("data", dataHandler);
1277
- globalTcpConnections.delete(this.connectionId);
1278
- reject(new Error("TCP connection timeout"));
1279
- }
1280
- }, this.timeout);
1281
- const executeQuery = () => {
1282
- const dmlIndex = args.findIndex((arg) => arg === "--dml");
1283
- const dmlJson = dmlIndex !== -1 ? args[dmlIndex + 1] : null;
1284
- if (!dmlJson) {
1285
- clearTimeout(timeout);
1286
- if (!isResolved) {
1287
- isResolved = true;
1288
- reject(new Error("No DML found in arguments"));
1289
- }
1290
- return;
1291
- }
1292
- const command = {
1293
- action: "execute",
1294
- dml: dmlJson
1295
- };
1296
- const commandStr = JSON.stringify(command);
1297
- const canWrite = client.write(commandStr);
1298
- if (!canWrite) {
1299
- client.once("drain", () => {
1300
- });
1301
- }
1302
- };
1303
- const dataHandler = (data) => {
1304
- responseBuffer += data.toString();
1305
- const match = responseBuffer.match(/PROCESS_RESPONSE:(\{.*\})/);
1306
- if (match && !isResolved) {
1307
- isResolved = true;
1308
- clearTimeout(timeout);
1309
- try {
1310
- const response = JSON.parse(match[1]);
1311
- responseBuffer = "";
1312
- client.removeListener("data", dataHandler);
1313
- resolve5({
1314
- status: response.status,
1315
- message: response.message,
1316
- data: response.data
1317
- });
1318
- } catch (error) {
1319
- client.removeListener("data", dataHandler);
1320
- reject(new Error("Failed to parse TCP response"));
1321
- }
1322
- }
1323
- };
1324
- const errorHandler = (error) => {
1325
- if (!isResolved) {
1326
- isResolved = true;
1327
- clearTimeout(timeout);
1328
- globalTcpConnections.delete(this.connectionId);
1329
- client.removeListener("data", dataHandler);
1330
- reject(error);
1331
- }
1332
- };
1333
- const closeHandler = () => {
1334
- globalTcpConnections.delete(this.connectionId);
1335
- if (!isResolved) {
1336
- isResolved = true;
1337
- clearTimeout(timeout);
1338
- client.removeListener("data", dataHandler);
1339
- reject(new Error("Connection closed unexpectedly"));
1340
- }
1341
- };
1342
- if (isNewConnection) {
1343
- client.connect(this.tcpPort, "127.0.0.1", () => {
1344
- clearTimeout(timeout);
1345
- globalTcpConnections.set(this.connectionId, client);
1346
- client.on("error", errorHandler);
1347
- client.on("close", closeHandler);
1348
- client.on("data", dataHandler);
1349
- executeQuery();
1350
- });
1351
- } else {
1352
- clearTimeout(timeout);
1353
- client.on("data", dataHandler);
1354
- executeQuery();
1355
- }
1356
- });
1357
- }
1358
1259
  async createProcess(binary, args) {
1359
1260
  await this.initializeBinary();
1360
1261
  if (!this.binary) {