@dbcube/core 3.0.10 → 3.0.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 +159 -27
- 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 +159 -27
- 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;
|
|
@@ -851,6 +881,7 @@ var QueryEngine = class {
|
|
|
851
881
|
if (!serverInfo || !serverInfo.process || serverInfo.process.killed) {
|
|
852
882
|
await this.startTcpServer();
|
|
853
883
|
await this.waitForServerReady();
|
|
884
|
+
await this.initializeConnectionPool();
|
|
854
885
|
}
|
|
855
886
|
return this.sendTcpRequestFast(args);
|
|
856
887
|
}
|
|
@@ -886,15 +917,30 @@ var QueryEngine = class {
|
|
|
886
917
|
sleep(ms) {
|
|
887
918
|
return new Promise((resolve5) => setTimeout(resolve5, ms));
|
|
888
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
|
+
}
|
|
889
937
|
getCachedDML(dmlJson) {
|
|
890
|
-
|
|
891
|
-
|
|
938
|
+
const cached = queryCache.get(dmlJson);
|
|
939
|
+
if (cached) {
|
|
940
|
+
return cached;
|
|
892
941
|
}
|
|
893
942
|
const parsed = JSON.parse(dmlJson);
|
|
894
|
-
|
|
895
|
-
queryCache.set(dmlJson, parsed);
|
|
896
|
-
cacheSize++;
|
|
897
|
-
}
|
|
943
|
+
queryCache.set(dmlJson, parsed);
|
|
898
944
|
return parsed;
|
|
899
945
|
}
|
|
900
946
|
async startTcpServer() {
|
|
@@ -918,7 +964,6 @@ var QueryEngine = class {
|
|
|
918
964
|
if (output.includes("TCP Server listening on")) {
|
|
919
965
|
if (!started) {
|
|
920
966
|
started = true;
|
|
921
|
-
clearTimeout(timeout);
|
|
922
967
|
globalTcpServers.set(this.connectionId, {
|
|
923
968
|
port: this.tcpPort,
|
|
924
969
|
process: serverProcess
|
|
@@ -935,7 +980,6 @@ var QueryEngine = class {
|
|
|
935
980
|
});
|
|
936
981
|
serverProcess.on("error", (error) => {
|
|
937
982
|
if (!started) {
|
|
938
|
-
clearTimeout(timeout);
|
|
939
983
|
reject(error);
|
|
940
984
|
}
|
|
941
985
|
});
|
|
@@ -959,7 +1003,6 @@ var QueryEngine = class {
|
|
|
959
1003
|
if (!dmlJson) {
|
|
960
1004
|
if (!isResolved) {
|
|
961
1005
|
isResolved = true;
|
|
962
|
-
clearTimeout(timeout);
|
|
963
1006
|
client.destroy();
|
|
964
1007
|
reject(new Error("No DML found in arguments"));
|
|
965
1008
|
}
|
|
@@ -976,7 +1019,6 @@ var QueryEngine = class {
|
|
|
976
1019
|
const match = responseBuffer.match(/PROCESS_RESPONSE:(\{.*\})/);
|
|
977
1020
|
if (match && !isResolved) {
|
|
978
1021
|
isResolved = true;
|
|
979
|
-
clearTimeout(timeout);
|
|
980
1022
|
client.destroy();
|
|
981
1023
|
try {
|
|
982
1024
|
const response = JSON.parse(match[1]);
|
|
@@ -993,13 +1035,11 @@ var QueryEngine = class {
|
|
|
993
1035
|
client.on("error", (error) => {
|
|
994
1036
|
if (!isResolved) {
|
|
995
1037
|
isResolved = true;
|
|
996
|
-
clearTimeout(timeout);
|
|
997
1038
|
reject(error);
|
|
998
1039
|
}
|
|
999
1040
|
});
|
|
1000
1041
|
client.on("close", () => {
|
|
1001
1042
|
if (!isResolved) {
|
|
1002
|
-
clearTimeout(timeout);
|
|
1003
1043
|
if (!responseBuffer.includes("PROCESS_RESPONSE:")) {
|
|
1004
1044
|
reject(new Error("Connection closed without valid response"));
|
|
1005
1045
|
}
|
|
@@ -1008,18 +1048,24 @@ var QueryEngine = class {
|
|
|
1008
1048
|
});
|
|
1009
1049
|
}
|
|
1010
1050
|
async sendTcpRequestFast(args) {
|
|
1011
|
-
|
|
1012
|
-
|
|
1051
|
+
if (!connectionPools.has(this.connectionId)) {
|
|
1052
|
+
return await this.createAndPoolConnection(args);
|
|
1053
|
+
}
|
|
1054
|
+
const pool = connectionPools.get(this.connectionId);
|
|
1055
|
+
if (pool.length > 0) {
|
|
1056
|
+
const connection = pool.pop();
|
|
1013
1057
|
try {
|
|
1014
|
-
|
|
1058
|
+
const result = await this.sendUltraFast(connection, args);
|
|
1059
|
+
pool.push(connection);
|
|
1060
|
+
return result;
|
|
1015
1061
|
} catch (error) {
|
|
1016
|
-
|
|
1017
|
-
|
|
1062
|
+
connection.destroy();
|
|
1063
|
+
return await this.createAndPoolConnection(args);
|
|
1018
1064
|
}
|
|
1019
1065
|
}
|
|
1020
|
-
return await this.
|
|
1066
|
+
return await this.createAndPoolConnection(args);
|
|
1021
1067
|
}
|
|
1022
|
-
async
|
|
1068
|
+
async sendUltraFast(connection, args) {
|
|
1023
1069
|
return new Promise((resolve5, reject) => {
|
|
1024
1070
|
const dmlIndex = args.findIndex((arg) => arg === "--dml");
|
|
1025
1071
|
const dmlJson = dmlIndex !== -1 ? args[dmlIndex + 1] : null;
|
|
@@ -1029,20 +1075,96 @@ var QueryEngine = class {
|
|
|
1029
1075
|
}
|
|
1030
1076
|
let responseBuffer = "";
|
|
1031
1077
|
let isResolved = false;
|
|
1032
|
-
const
|
|
1078
|
+
const onData = (data) => {
|
|
1079
|
+
responseBuffer += data.toString();
|
|
1080
|
+
const match = responseBuffer.match(/PROCESS_RESPONSE:(\{.*\})/);
|
|
1081
|
+
if (match && !isResolved) {
|
|
1082
|
+
isResolved = true;
|
|
1083
|
+
connection.off("data", onData);
|
|
1084
|
+
connection.off("error", onError);
|
|
1085
|
+
connection.off("close", onClose);
|
|
1086
|
+
try {
|
|
1087
|
+
const response = JSON.parse(match[1]);
|
|
1088
|
+
resolve5({
|
|
1089
|
+
status: response.status,
|
|
1090
|
+
message: response.message,
|
|
1091
|
+
data: response.data
|
|
1092
|
+
});
|
|
1093
|
+
} catch (error) {
|
|
1094
|
+
reject(new Error("Failed to parse TCP response"));
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
};
|
|
1098
|
+
const onError = (error) => {
|
|
1033
1099
|
if (!isResolved) {
|
|
1034
1100
|
isResolved = true;
|
|
1035
|
-
|
|
1101
|
+
connection.off("data", onData);
|
|
1102
|
+
connection.off("error", onError);
|
|
1103
|
+
connection.off("close", onClose);
|
|
1104
|
+
reject(error);
|
|
1036
1105
|
}
|
|
1037
|
-
}
|
|
1106
|
+
};
|
|
1107
|
+
const onClose = () => {
|
|
1108
|
+
if (!isResolved) {
|
|
1109
|
+
isResolved = true;
|
|
1110
|
+
connection.off("data", onData);
|
|
1111
|
+
connection.off("error", onError);
|
|
1112
|
+
connection.off("close", onClose);
|
|
1113
|
+
connection.off("close", onClose);
|
|
1114
|
+
reject(new Error("Connection closed unexpectedly"));
|
|
1115
|
+
}
|
|
1116
|
+
};
|
|
1117
|
+
connection.on("data", onData);
|
|
1118
|
+
connection.on("error", onError);
|
|
1119
|
+
connection.on("close", onClose);
|
|
1120
|
+
const command = `{"action":"execute","dml":${dmlJson}}`;
|
|
1121
|
+
connection.write(command);
|
|
1122
|
+
});
|
|
1123
|
+
}
|
|
1124
|
+
async createAndPoolConnection(args) {
|
|
1125
|
+
const connection = await this.createPooledConnection();
|
|
1126
|
+
if (!connectionPools.has(this.connectionId)) {
|
|
1127
|
+
connectionPools.set(this.connectionId, []);
|
|
1128
|
+
}
|
|
1129
|
+
const result = await this.sendUltraFast(connection, args);
|
|
1130
|
+
const pool = connectionPools.get(this.connectionId);
|
|
1131
|
+
if (pool.length < MAX_POOL_SIZE) {
|
|
1132
|
+
pool.push(connection);
|
|
1133
|
+
} else {
|
|
1134
|
+
connection.destroy();
|
|
1135
|
+
}
|
|
1136
|
+
return result;
|
|
1137
|
+
}
|
|
1138
|
+
async createPooledConnection() {
|
|
1139
|
+
return new Promise((resolve5, reject) => {
|
|
1140
|
+
const client = new net.Socket();
|
|
1141
|
+
client.setNoDelay(true);
|
|
1142
|
+
client.setKeepAlive(true, 0);
|
|
1143
|
+
client.connect(this.tcpPort, "127.0.0.1", () => {
|
|
1144
|
+
resolve5(client);
|
|
1145
|
+
});
|
|
1146
|
+
client.on("error", reject);
|
|
1147
|
+
});
|
|
1148
|
+
}
|
|
1149
|
+
async sendOnExistingConnection(connection, args) {
|
|
1150
|
+
return new Promise((resolve5, reject) => {
|
|
1151
|
+
const dmlIndex = args.findIndex((arg) => arg === "--dml");
|
|
1152
|
+
const dmlJson = dmlIndex !== -1 ? args[dmlIndex + 1] : null;
|
|
1153
|
+
if (!dmlJson) {
|
|
1154
|
+
reject(new Error("No DML found in arguments"));
|
|
1155
|
+
return;
|
|
1156
|
+
}
|
|
1157
|
+
const dmlParsed = this.getCachedDML(dmlJson);
|
|
1158
|
+
let responseBuffer = "";
|
|
1159
|
+
let isResolved = false;
|
|
1038
1160
|
const onData = (data) => {
|
|
1039
1161
|
responseBuffer += data.toString();
|
|
1040
1162
|
const match = responseBuffer.match(/PROCESS_RESPONSE:(\{.*\})/);
|
|
1041
1163
|
if (match && !isResolved) {
|
|
1042
1164
|
isResolved = true;
|
|
1043
|
-
clearTimeout(timeout);
|
|
1044
1165
|
connection.off("data", onData);
|
|
1045
1166
|
connection.off("error", onError);
|
|
1167
|
+
connection.off("close", onClose);
|
|
1046
1168
|
try {
|
|
1047
1169
|
const response = JSON.parse(match[1]);
|
|
1048
1170
|
resolve5({
|
|
@@ -1058,14 +1180,24 @@ var QueryEngine = class {
|
|
|
1058
1180
|
const onError = (error) => {
|
|
1059
1181
|
if (!isResolved) {
|
|
1060
1182
|
isResolved = true;
|
|
1061
|
-
clearTimeout(timeout);
|
|
1062
1183
|
connection.off("data", onData);
|
|
1063
1184
|
connection.off("error", onError);
|
|
1185
|
+
connection.off("close", onClose);
|
|
1064
1186
|
reject(error);
|
|
1065
1187
|
}
|
|
1066
1188
|
};
|
|
1189
|
+
const onClose = () => {
|
|
1190
|
+
if (!isResolved) {
|
|
1191
|
+
isResolved = true;
|
|
1192
|
+
connection.off("data", onData);
|
|
1193
|
+
connection.off("error", onError);
|
|
1194
|
+
connection.off("close", onClose);
|
|
1195
|
+
reject(new Error("Connection closed unexpectedly"));
|
|
1196
|
+
}
|
|
1197
|
+
};
|
|
1067
1198
|
connection.on("data", onData);
|
|
1068
1199
|
connection.on("error", onError);
|
|
1200
|
+
connection.on("close", onClose);
|
|
1069
1201
|
const command = {
|
|
1070
1202
|
action: "execute",
|
|
1071
1203
|
dml: dmlJson
|