@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.d.mts
CHANGED
|
@@ -45,10 +45,14 @@ declare class QueryEngine {
|
|
|
45
45
|
private waitForServerReady;
|
|
46
46
|
private isServerResponding;
|
|
47
47
|
private sleep;
|
|
48
|
+
private initializeConnectionPool;
|
|
48
49
|
private getCachedDML;
|
|
49
50
|
private startTcpServer;
|
|
50
51
|
private sendTcpRequest;
|
|
51
52
|
private sendTcpRequestFast;
|
|
53
|
+
private sendUltraFast;
|
|
54
|
+
private createAndPoolConnection;
|
|
55
|
+
private createPooledConnection;
|
|
52
56
|
private sendOnExistingConnection;
|
|
53
57
|
private createPersistentConnection;
|
|
54
58
|
private createProcess;
|
package/dist/index.d.ts
CHANGED
|
@@ -45,10 +45,14 @@ declare class QueryEngine {
|
|
|
45
45
|
private waitForServerReady;
|
|
46
46
|
private isServerResponding;
|
|
47
47
|
private sleep;
|
|
48
|
+
private initializeConnectionPool;
|
|
48
49
|
private getCachedDML;
|
|
49
50
|
private startTcpServer;
|
|
50
51
|
private sendTcpRequest;
|
|
51
52
|
private sendTcpRequestFast;
|
|
53
|
+
private sendUltraFast;
|
|
54
|
+
private createAndPoolConnection;
|
|
55
|
+
private createPooledConnection;
|
|
52
56
|
private sendOnExistingConnection;
|
|
53
57
|
private createPersistentConnection;
|
|
54
58
|
private createProcess;
|
package/dist/index.js
CHANGED
|
@@ -730,9 +730,39 @@ import * as net from "net";
|
|
|
730
730
|
import { spawn as spawn2 } from "child_process";
|
|
731
731
|
var globalTcpServers = /* @__PURE__ */ new Map();
|
|
732
732
|
var globalTcpConnections = /* @__PURE__ */ new Map();
|
|
733
|
-
var
|
|
734
|
-
var
|
|
735
|
-
var
|
|
733
|
+
var connectionPools = /* @__PURE__ */ new Map();
|
|
734
|
+
var MAX_POOL_SIZE = 3;
|
|
735
|
+
var LRUCache = class {
|
|
736
|
+
cache = /* @__PURE__ */ new Map();
|
|
737
|
+
maxSize;
|
|
738
|
+
constructor(maxSize) {
|
|
739
|
+
this.maxSize = maxSize;
|
|
740
|
+
}
|
|
741
|
+
get(key) {
|
|
742
|
+
if (this.cache.has(key)) {
|
|
743
|
+
const value = this.cache.get(key);
|
|
744
|
+
this.cache.delete(key);
|
|
745
|
+
this.cache.set(key, value);
|
|
746
|
+
return value;
|
|
747
|
+
}
|
|
748
|
+
return void 0;
|
|
749
|
+
}
|
|
750
|
+
set(key, value) {
|
|
751
|
+
if (this.cache.has(key)) {
|
|
752
|
+
this.cache.delete(key);
|
|
753
|
+
} else if (this.cache.size >= this.maxSize) {
|
|
754
|
+
const firstKey = this.cache.keys().next().value;
|
|
755
|
+
if (firstKey !== void 0) {
|
|
756
|
+
this.cache.delete(firstKey);
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
this.cache.set(key, value);
|
|
760
|
+
}
|
|
761
|
+
size() {
|
|
762
|
+
return this.cache.size;
|
|
763
|
+
}
|
|
764
|
+
};
|
|
765
|
+
var queryCache = new LRUCache(500);
|
|
736
766
|
var QueryEngine = class {
|
|
737
767
|
name;
|
|
738
768
|
config;
|
|
@@ -849,11 +879,10 @@ var QueryEngine = class {
|
|
|
849
879
|
async executeWithTcpServer(args) {
|
|
850
880
|
const serverInfo = globalTcpServers.get(this.connectionId);
|
|
851
881
|
if (!serverInfo || !serverInfo.process || serverInfo.process.killed) {
|
|
852
|
-
console.log("\u{1F680} Starting TCP server for ultra-fast queries...");
|
|
853
882
|
await this.startTcpServer();
|
|
854
883
|
await this.waitForServerReady();
|
|
884
|
+
await this.initializeConnectionPool();
|
|
855
885
|
}
|
|
856
|
-
console.log("\u26A1 Using TCP server (ultra-fast)");
|
|
857
886
|
return this.sendTcpRequestFast(args);
|
|
858
887
|
}
|
|
859
888
|
async waitForServerReady() {
|
|
@@ -863,7 +892,6 @@ var QueryEngine = class {
|
|
|
863
892
|
if (await this.isServerResponding()) {
|
|
864
893
|
return;
|
|
865
894
|
}
|
|
866
|
-
console.log(`\u23F3 Waiting for TCP server to be ready... (${i + 1}/${maxRetries})`);
|
|
867
895
|
await this.sleep(retryDelay);
|
|
868
896
|
}
|
|
869
897
|
throw new Error("TCP server failed to become ready within timeout");
|
|
@@ -889,15 +917,30 @@ var QueryEngine = class {
|
|
|
889
917
|
sleep(ms) {
|
|
890
918
|
return new Promise((resolve5) => setTimeout(resolve5, ms));
|
|
891
919
|
}
|
|
920
|
+
async initializeConnectionPool() {
|
|
921
|
+
console.log("\u{1F3CA} Initializing connection pool...");
|
|
922
|
+
if (!connectionPools.has(this.connectionId)) {
|
|
923
|
+
connectionPools.set(this.connectionId, []);
|
|
924
|
+
}
|
|
925
|
+
const pool = connectionPools.get(this.connectionId);
|
|
926
|
+
for (let i = 0; i < MAX_POOL_SIZE; i++) {
|
|
927
|
+
try {
|
|
928
|
+
const connection = await this.createPooledConnection();
|
|
929
|
+
pool.push(connection);
|
|
930
|
+
console.log(`\u2705 Pool connection ${i + 1}/${MAX_POOL_SIZE} created`);
|
|
931
|
+
} catch (error) {
|
|
932
|
+
console.error(`\u274C Failed to create pool connection ${i + 1}:`, error);
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
console.log(`\u{1F680} Connection pool ready with ${pool.length} connections`);
|
|
936
|
+
}
|
|
892
937
|
getCachedDML(dmlJson) {
|
|
893
|
-
|
|
894
|
-
|
|
938
|
+
const cached = queryCache.get(dmlJson);
|
|
939
|
+
if (cached) {
|
|
940
|
+
return cached;
|
|
895
941
|
}
|
|
896
942
|
const parsed = JSON.parse(dmlJson);
|
|
897
|
-
|
|
898
|
-
queryCache.set(dmlJson, parsed);
|
|
899
|
-
cacheSize++;
|
|
900
|
-
}
|
|
943
|
+
queryCache.set(dmlJson, parsed);
|
|
901
944
|
return parsed;
|
|
902
945
|
}
|
|
903
946
|
async startTcpServer() {
|
|
@@ -906,7 +949,6 @@ var QueryEngine = class {
|
|
|
906
949
|
throw new Error("Binary not initialized");
|
|
907
950
|
}
|
|
908
951
|
this.tcpPort = await this.findAvailablePort(this.tcpPort);
|
|
909
|
-
console.log(`\u{1F310} Using port ${this.tcpPort} for TCP server`);
|
|
910
952
|
return new Promise((resolve5, reject) => {
|
|
911
953
|
const serverArgs = [...this.arguments, "--action", "server", "--port", this.tcpPort.toString()];
|
|
912
954
|
const serverProcess = spawn2(this.binary["query_engine"], serverArgs);
|
|
@@ -919,7 +961,6 @@ var QueryEngine = class {
|
|
|
919
961
|
}, 15e3);
|
|
920
962
|
serverProcess.stdout.on("data", (data) => {
|
|
921
963
|
const output = data.toString();
|
|
922
|
-
console.log(`[TCP Server] ${output.trim()}`);
|
|
923
964
|
if (output.includes("TCP Server listening on")) {
|
|
924
965
|
if (!started) {
|
|
925
966
|
started = true;
|
|
@@ -936,7 +977,6 @@ var QueryEngine = class {
|
|
|
936
977
|
console.error(`[TCP Server Error] ${data.toString().trim()}`);
|
|
937
978
|
});
|
|
938
979
|
serverProcess.on("close", (code) => {
|
|
939
|
-
console.log(`[TCP Server] Process exited with code ${code}`);
|
|
940
980
|
globalTcpServers.delete(this.connectionId);
|
|
941
981
|
});
|
|
942
982
|
serverProcess.on("error", (error) => {
|
|
@@ -1014,16 +1054,100 @@ var QueryEngine = class {
|
|
|
1014
1054
|
});
|
|
1015
1055
|
}
|
|
1016
1056
|
async sendTcpRequestFast(args) {
|
|
1017
|
-
|
|
1018
|
-
|
|
1057
|
+
if (!connectionPools.has(this.connectionId)) {
|
|
1058
|
+
return await this.createAndPoolConnection(args);
|
|
1059
|
+
}
|
|
1060
|
+
const pool = connectionPools.get(this.connectionId);
|
|
1061
|
+
if (pool.length > 0) {
|
|
1062
|
+
const connection = pool.pop();
|
|
1019
1063
|
try {
|
|
1020
|
-
|
|
1064
|
+
const result = await this.sendUltraFast(connection, args);
|
|
1065
|
+
pool.push(connection);
|
|
1066
|
+
return result;
|
|
1021
1067
|
} catch (error) {
|
|
1022
|
-
|
|
1023
|
-
|
|
1068
|
+
connection.destroy();
|
|
1069
|
+
return await this.createAndPoolConnection(args);
|
|
1024
1070
|
}
|
|
1025
1071
|
}
|
|
1026
|
-
return await this.
|
|
1072
|
+
return await this.createAndPoolConnection(args);
|
|
1073
|
+
}
|
|
1074
|
+
async sendUltraFast(connection, args) {
|
|
1075
|
+
return new Promise((resolve5, reject) => {
|
|
1076
|
+
const dmlIndex = args.findIndex((arg) => arg === "--dml");
|
|
1077
|
+
const dmlJson = dmlIndex !== -1 ? args[dmlIndex + 1] : null;
|
|
1078
|
+
if (!dmlJson) {
|
|
1079
|
+
reject(new Error("No DML found in arguments"));
|
|
1080
|
+
return;
|
|
1081
|
+
}
|
|
1082
|
+
let responseBuffer = "";
|
|
1083
|
+
let isResolved = false;
|
|
1084
|
+
const timeout = setTimeout(() => {
|
|
1085
|
+
if (!isResolved) {
|
|
1086
|
+
isResolved = true;
|
|
1087
|
+
connection.off("data", onData);
|
|
1088
|
+
connection.off("error", onError);
|
|
1089
|
+
reject(new Error("Ultra-fast timeout"));
|
|
1090
|
+
}
|
|
1091
|
+
}, 50);
|
|
1092
|
+
const onData = (data) => {
|
|
1093
|
+
responseBuffer += data.toString();
|
|
1094
|
+
const match = responseBuffer.match(/PROCESS_RESPONSE:(\{.*\})/);
|
|
1095
|
+
if (match && !isResolved) {
|
|
1096
|
+
isResolved = true;
|
|
1097
|
+
clearTimeout(timeout);
|
|
1098
|
+
connection.off("data", onData);
|
|
1099
|
+
connection.off("error", onError);
|
|
1100
|
+
try {
|
|
1101
|
+
const response = JSON.parse(match[1]);
|
|
1102
|
+
resolve5({
|
|
1103
|
+
status: response.status,
|
|
1104
|
+
message: response.message,
|
|
1105
|
+
data: response.data
|
|
1106
|
+
});
|
|
1107
|
+
} catch (error) {
|
|
1108
|
+
reject(new Error("Failed to parse TCP response"));
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
};
|
|
1112
|
+
const onError = (error) => {
|
|
1113
|
+
if (!isResolved) {
|
|
1114
|
+
isResolved = true;
|
|
1115
|
+
clearTimeout(timeout);
|
|
1116
|
+
connection.off("data", onData);
|
|
1117
|
+
connection.off("error", onError);
|
|
1118
|
+
reject(error);
|
|
1119
|
+
}
|
|
1120
|
+
};
|
|
1121
|
+
connection.on("data", onData);
|
|
1122
|
+
connection.on("error", onError);
|
|
1123
|
+
const command = `{"action":"execute","dml":${dmlJson}}`;
|
|
1124
|
+
connection.write(command);
|
|
1125
|
+
});
|
|
1126
|
+
}
|
|
1127
|
+
async createAndPoolConnection(args) {
|
|
1128
|
+
const connection = await this.createPooledConnection();
|
|
1129
|
+
if (!connectionPools.has(this.connectionId)) {
|
|
1130
|
+
connectionPools.set(this.connectionId, []);
|
|
1131
|
+
}
|
|
1132
|
+
const result = await this.sendUltraFast(connection, args);
|
|
1133
|
+
const pool = connectionPools.get(this.connectionId);
|
|
1134
|
+
if (pool.length < MAX_POOL_SIZE) {
|
|
1135
|
+
pool.push(connection);
|
|
1136
|
+
} else {
|
|
1137
|
+
connection.destroy();
|
|
1138
|
+
}
|
|
1139
|
+
return result;
|
|
1140
|
+
}
|
|
1141
|
+
async createPooledConnection() {
|
|
1142
|
+
return new Promise((resolve5, reject) => {
|
|
1143
|
+
const client = new net.Socket();
|
|
1144
|
+
client.setNoDelay(true);
|
|
1145
|
+
client.setKeepAlive(true, 0);
|
|
1146
|
+
client.connect(this.tcpPort, "127.0.0.1", () => {
|
|
1147
|
+
resolve5(client);
|
|
1148
|
+
});
|
|
1149
|
+
client.on("error", reject);
|
|
1150
|
+
});
|
|
1027
1151
|
}
|
|
1028
1152
|
async sendOnExistingConnection(connection, args) {
|
|
1029
1153
|
return new Promise((resolve5, reject) => {
|
|
@@ -1033,6 +1157,7 @@ var QueryEngine = class {
|
|
|
1033
1157
|
reject(new Error("No DML found in arguments"));
|
|
1034
1158
|
return;
|
|
1035
1159
|
}
|
|
1160
|
+
const dmlParsed = this.getCachedDML(dmlJson);
|
|
1036
1161
|
let responseBuffer = "";
|
|
1037
1162
|
let isResolved = false;
|
|
1038
1163
|
const timeout = setTimeout(() => {
|
|
@@ -1240,7 +1365,6 @@ var QueryEngine = class {
|
|
|
1240
1365
|
}
|
|
1241
1366
|
const serverInfo = globalTcpServers.get(this.connectionId);
|
|
1242
1367
|
if (serverInfo && serverInfo.process && !serverInfo.process.killed) {
|
|
1243
|
-
console.log("\u{1F50C} Stopping TCP server...");
|
|
1244
1368
|
serverInfo.process.kill();
|
|
1245
1369
|
globalTcpServers.delete(this.connectionId);
|
|
1246
1370
|
return {
|