@dbcube/core 3.0.10 → 3.0.12

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
@@ -768,9 +768,39 @@ var net = __toESM(require("net"));
768
768
  var import_child_process2 = require("child_process");
769
769
  var globalTcpServers = /* @__PURE__ */ new Map();
770
770
  var globalTcpConnections = /* @__PURE__ */ new Map();
771
- var queryCache = /* @__PURE__ */ new Map();
772
- var cacheSize = 0;
773
- var MAX_CACHE_SIZE = 500;
771
+ var connectionPools = /* @__PURE__ */ new Map();
772
+ var MAX_POOL_SIZE = 3;
773
+ var LRUCache = class {
774
+ cache = /* @__PURE__ */ new Map();
775
+ maxSize;
776
+ constructor(maxSize) {
777
+ this.maxSize = maxSize;
778
+ }
779
+ get(key) {
780
+ if (this.cache.has(key)) {
781
+ const value = this.cache.get(key);
782
+ this.cache.delete(key);
783
+ this.cache.set(key, value);
784
+ return value;
785
+ }
786
+ return void 0;
787
+ }
788
+ set(key, value) {
789
+ if (this.cache.has(key)) {
790
+ this.cache.delete(key);
791
+ } else if (this.cache.size >= this.maxSize) {
792
+ const firstKey = this.cache.keys().next().value;
793
+ if (firstKey !== void 0) {
794
+ this.cache.delete(firstKey);
795
+ }
796
+ }
797
+ this.cache.set(key, value);
798
+ }
799
+ size() {
800
+ return this.cache.size;
801
+ }
802
+ };
803
+ var queryCache = new LRUCache(500);
774
804
  var QueryEngine = class {
775
805
  name;
776
806
  config;
@@ -889,6 +919,7 @@ var QueryEngine = class {
889
919
  if (!serverInfo || !serverInfo.process || serverInfo.process.killed) {
890
920
  await this.startTcpServer();
891
921
  await this.waitForServerReady();
922
+ await this.initializeConnectionPool();
892
923
  }
893
924
  return this.sendTcpRequestFast(args);
894
925
  }
@@ -924,15 +955,30 @@ var QueryEngine = class {
924
955
  sleep(ms) {
925
956
  return new Promise((resolve5) => setTimeout(resolve5, ms));
926
957
  }
958
+ async initializeConnectionPool() {
959
+ console.log("\u{1F3CA} Initializing connection pool...");
960
+ if (!connectionPools.has(this.connectionId)) {
961
+ connectionPools.set(this.connectionId, []);
962
+ }
963
+ const pool = connectionPools.get(this.connectionId);
964
+ for (let i = 0; i < MAX_POOL_SIZE; i++) {
965
+ try {
966
+ const connection = await this.createPooledConnection();
967
+ pool.push(connection);
968
+ console.log(`\u2705 Pool connection ${i + 1}/${MAX_POOL_SIZE} created`);
969
+ } catch (error) {
970
+ console.error(`\u274C Failed to create pool connection ${i + 1}:`, error);
971
+ }
972
+ }
973
+ console.log(`\u{1F680} Connection pool ready with ${pool.length} connections`);
974
+ }
927
975
  getCachedDML(dmlJson) {
928
- if (queryCache.has(dmlJson)) {
929
- return queryCache.get(dmlJson);
976
+ const cached = queryCache.get(dmlJson);
977
+ if (cached) {
978
+ return cached;
930
979
  }
931
980
  const parsed = JSON.parse(dmlJson);
932
- if (cacheSize < MAX_CACHE_SIZE) {
933
- queryCache.set(dmlJson, parsed);
934
- cacheSize++;
935
- }
981
+ queryCache.set(dmlJson, parsed);
936
982
  return parsed;
937
983
  }
938
984
  async startTcpServer() {
@@ -1046,16 +1092,100 @@ var QueryEngine = class {
1046
1092
  });
1047
1093
  }
1048
1094
  async sendTcpRequestFast(args) {
1049
- const existingConnection = globalTcpConnections.get(this.connectionId);
1050
- if (existingConnection && existingConnection.readyState === "open") {
1095
+ if (!connectionPools.has(this.connectionId)) {
1096
+ return await this.createAndPoolConnection(args);
1097
+ }
1098
+ const pool = connectionPools.get(this.connectionId);
1099
+ if (pool.length > 0) {
1100
+ const connection = pool.pop();
1051
1101
  try {
1052
- return await this.sendOnExistingConnection(existingConnection, args);
1102
+ const result = await this.sendUltraFast(connection, args);
1103
+ pool.push(connection);
1104
+ return result;
1053
1105
  } catch (error) {
1054
- globalTcpConnections.delete(this.connectionId);
1055
- existingConnection.destroy();
1106
+ connection.destroy();
1107
+ return await this.createAndPoolConnection(args);
1056
1108
  }
1057
1109
  }
1058
- return await this.createPersistentConnection(args);
1110
+ return await this.createAndPoolConnection(args);
1111
+ }
1112
+ async sendUltraFast(connection, args) {
1113
+ return new Promise((resolve5, reject) => {
1114
+ const dmlIndex = args.findIndex((arg) => arg === "--dml");
1115
+ const dmlJson = dmlIndex !== -1 ? args[dmlIndex + 1] : null;
1116
+ if (!dmlJson) {
1117
+ reject(new Error("No DML found in arguments"));
1118
+ return;
1119
+ }
1120
+ let responseBuffer = "";
1121
+ let isResolved = false;
1122
+ const timeout = setTimeout(() => {
1123
+ if (!isResolved) {
1124
+ isResolved = true;
1125
+ connection.off("data", onData);
1126
+ connection.off("error", onError);
1127
+ reject(new Error("Ultra-fast timeout"));
1128
+ }
1129
+ }, 50);
1130
+ const onData = (data) => {
1131
+ responseBuffer += data.toString();
1132
+ const match = responseBuffer.match(/PROCESS_RESPONSE:(\{.*\})/);
1133
+ if (match && !isResolved) {
1134
+ isResolved = true;
1135
+ clearTimeout(timeout);
1136
+ connection.off("data", onData);
1137
+ connection.off("error", onError);
1138
+ try {
1139
+ const response = JSON.parse(match[1]);
1140
+ resolve5({
1141
+ status: response.status,
1142
+ message: response.message,
1143
+ data: response.data
1144
+ });
1145
+ } catch (error) {
1146
+ reject(new Error("Failed to parse TCP response"));
1147
+ }
1148
+ }
1149
+ };
1150
+ const onError = (error) => {
1151
+ if (!isResolved) {
1152
+ isResolved = true;
1153
+ clearTimeout(timeout);
1154
+ connection.off("data", onData);
1155
+ connection.off("error", onError);
1156
+ reject(error);
1157
+ }
1158
+ };
1159
+ connection.on("data", onData);
1160
+ connection.on("error", onError);
1161
+ const command = `{"action":"execute","dml":${dmlJson}}`;
1162
+ connection.write(command);
1163
+ });
1164
+ }
1165
+ async createAndPoolConnection(args) {
1166
+ const connection = await this.createPooledConnection();
1167
+ if (!connectionPools.has(this.connectionId)) {
1168
+ connectionPools.set(this.connectionId, []);
1169
+ }
1170
+ const result = await this.sendUltraFast(connection, args);
1171
+ const pool = connectionPools.get(this.connectionId);
1172
+ if (pool.length < MAX_POOL_SIZE) {
1173
+ pool.push(connection);
1174
+ } else {
1175
+ connection.destroy();
1176
+ }
1177
+ return result;
1178
+ }
1179
+ async createPooledConnection() {
1180
+ return new Promise((resolve5, reject) => {
1181
+ const client = new net.Socket();
1182
+ client.setNoDelay(true);
1183
+ client.setKeepAlive(true, 0);
1184
+ client.connect(this.tcpPort, "127.0.0.1", () => {
1185
+ resolve5(client);
1186
+ });
1187
+ client.on("error", reject);
1188
+ });
1059
1189
  }
1060
1190
  async sendOnExistingConnection(connection, args) {
1061
1191
  return new Promise((resolve5, reject) => {
@@ -1065,6 +1195,7 @@ var QueryEngine = class {
1065
1195
  reject(new Error("No DML found in arguments"));
1066
1196
  return;
1067
1197
  }
1198
+ const dmlParsed = this.getCachedDML(dmlJson);
1068
1199
  let responseBuffer = "";
1069
1200
  let isResolved = false;
1070
1201
  const timeout = setTimeout(() => {