@dbcube/core 3.0.9 → 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 +146 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +146 -22
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
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
|
|
772
|
-
var
|
|
773
|
-
var
|
|
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;
|
|
@@ -887,11 +917,10 @@ var QueryEngine = class {
|
|
|
887
917
|
async executeWithTcpServer(args) {
|
|
888
918
|
const serverInfo = globalTcpServers.get(this.connectionId);
|
|
889
919
|
if (!serverInfo || !serverInfo.process || serverInfo.process.killed) {
|
|
890
|
-
console.log("\u{1F680} Starting TCP server for ultra-fast queries...");
|
|
891
920
|
await this.startTcpServer();
|
|
892
921
|
await this.waitForServerReady();
|
|
922
|
+
await this.initializeConnectionPool();
|
|
893
923
|
}
|
|
894
|
-
console.log("\u26A1 Using TCP server (ultra-fast)");
|
|
895
924
|
return this.sendTcpRequestFast(args);
|
|
896
925
|
}
|
|
897
926
|
async waitForServerReady() {
|
|
@@ -901,7 +930,6 @@ var QueryEngine = class {
|
|
|
901
930
|
if (await this.isServerResponding()) {
|
|
902
931
|
return;
|
|
903
932
|
}
|
|
904
|
-
console.log(`\u23F3 Waiting for TCP server to be ready... (${i + 1}/${maxRetries})`);
|
|
905
933
|
await this.sleep(retryDelay);
|
|
906
934
|
}
|
|
907
935
|
throw new Error("TCP server failed to become ready within timeout");
|
|
@@ -927,15 +955,30 @@ var QueryEngine = class {
|
|
|
927
955
|
sleep(ms) {
|
|
928
956
|
return new Promise((resolve5) => setTimeout(resolve5, ms));
|
|
929
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
|
+
}
|
|
930
975
|
getCachedDML(dmlJson) {
|
|
931
|
-
|
|
932
|
-
|
|
976
|
+
const cached = queryCache.get(dmlJson);
|
|
977
|
+
if (cached) {
|
|
978
|
+
return cached;
|
|
933
979
|
}
|
|
934
980
|
const parsed = JSON.parse(dmlJson);
|
|
935
|
-
|
|
936
|
-
queryCache.set(dmlJson, parsed);
|
|
937
|
-
cacheSize++;
|
|
938
|
-
}
|
|
981
|
+
queryCache.set(dmlJson, parsed);
|
|
939
982
|
return parsed;
|
|
940
983
|
}
|
|
941
984
|
async startTcpServer() {
|
|
@@ -944,7 +987,6 @@ var QueryEngine = class {
|
|
|
944
987
|
throw new Error("Binary not initialized");
|
|
945
988
|
}
|
|
946
989
|
this.tcpPort = await this.findAvailablePort(this.tcpPort);
|
|
947
|
-
console.log(`\u{1F310} Using port ${this.tcpPort} for TCP server`);
|
|
948
990
|
return new Promise((resolve5, reject) => {
|
|
949
991
|
const serverArgs = [...this.arguments, "--action", "server", "--port", this.tcpPort.toString()];
|
|
950
992
|
const serverProcess = (0, import_child_process2.spawn)(this.binary["query_engine"], serverArgs);
|
|
@@ -957,7 +999,6 @@ var QueryEngine = class {
|
|
|
957
999
|
}, 15e3);
|
|
958
1000
|
serverProcess.stdout.on("data", (data) => {
|
|
959
1001
|
const output = data.toString();
|
|
960
|
-
console.log(`[TCP Server] ${output.trim()}`);
|
|
961
1002
|
if (output.includes("TCP Server listening on")) {
|
|
962
1003
|
if (!started) {
|
|
963
1004
|
started = true;
|
|
@@ -974,7 +1015,6 @@ var QueryEngine = class {
|
|
|
974
1015
|
console.error(`[TCP Server Error] ${data.toString().trim()}`);
|
|
975
1016
|
});
|
|
976
1017
|
serverProcess.on("close", (code) => {
|
|
977
|
-
console.log(`[TCP Server] Process exited with code ${code}`);
|
|
978
1018
|
globalTcpServers.delete(this.connectionId);
|
|
979
1019
|
});
|
|
980
1020
|
serverProcess.on("error", (error) => {
|
|
@@ -1052,16 +1092,100 @@ var QueryEngine = class {
|
|
|
1052
1092
|
});
|
|
1053
1093
|
}
|
|
1054
1094
|
async sendTcpRequestFast(args) {
|
|
1055
|
-
|
|
1056
|
-
|
|
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();
|
|
1057
1101
|
try {
|
|
1058
|
-
|
|
1102
|
+
const result = await this.sendUltraFast(connection, args);
|
|
1103
|
+
pool.push(connection);
|
|
1104
|
+
return result;
|
|
1059
1105
|
} catch (error) {
|
|
1060
|
-
|
|
1061
|
-
|
|
1106
|
+
connection.destroy();
|
|
1107
|
+
return await this.createAndPoolConnection(args);
|
|
1062
1108
|
}
|
|
1063
1109
|
}
|
|
1064
|
-
return await this.
|
|
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
|
+
});
|
|
1065
1189
|
}
|
|
1066
1190
|
async sendOnExistingConnection(connection, args) {
|
|
1067
1191
|
return new Promise((resolve5, reject) => {
|
|
@@ -1071,6 +1195,7 @@ var QueryEngine = class {
|
|
|
1071
1195
|
reject(new Error("No DML found in arguments"));
|
|
1072
1196
|
return;
|
|
1073
1197
|
}
|
|
1198
|
+
const dmlParsed = this.getCachedDML(dmlJson);
|
|
1074
1199
|
let responseBuffer = "";
|
|
1075
1200
|
let isResolved = false;
|
|
1076
1201
|
const timeout = setTimeout(() => {
|
|
@@ -1278,7 +1403,6 @@ var QueryEngine = class {
|
|
|
1278
1403
|
}
|
|
1279
1404
|
const serverInfo = globalTcpServers.get(this.connectionId);
|
|
1280
1405
|
if (serverInfo && serverInfo.process && !serverInfo.process.killed) {
|
|
1281
|
-
console.log("\u{1F50C} Stopping TCP server...");
|
|
1282
1406
|
serverInfo.process.kill();
|
|
1283
1407
|
globalTcpServers.delete(this.connectionId);
|
|
1284
1408
|
return {
|