@tachybase/module-multi-app 1.6.0 → 1.6.2
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/README.md +34 -34
- package/README.zh-CN.md +34 -34
- package/client.d.ts +1 -1
- package/client.js +1 -1
- package/dist/externalVersion.js +5 -5
- package/dist/locale/en-US.json +48 -48
- package/dist/locale/es-ES.json +9 -9
- package/dist/locale/ko_KR.json +11 -11
- package/dist/locale/pt-BR.json +9 -9
- package/dist/locale/zh-CN.json +58 -58
- package/dist/node_modules/mariadb/callback.js +43 -8
- package/dist/node_modules/mariadb/check-node.js +30 -0
- package/dist/node_modules/mariadb/lib/cluster-callback.js +84 -0
- package/dist/node_modules/mariadb/lib/cluster.js +446 -0
- package/dist/node_modules/mariadb/lib/cmd/batch-bulk.js +576 -177
- package/dist/node_modules/mariadb/lib/cmd/change-user.js +54 -44
- package/dist/node_modules/mariadb/lib/cmd/class/ok-packet.js +3 -2
- package/dist/node_modules/mariadb/lib/cmd/class/prepare-cache-wrapper.js +46 -0
- package/dist/node_modules/mariadb/lib/cmd/class/prepare-result-packet.js +141 -0
- package/dist/node_modules/mariadb/lib/cmd/class/prepare-wrapper.js +70 -0
- package/dist/node_modules/mariadb/lib/cmd/close-prepare.js +38 -0
- package/dist/node_modules/mariadb/lib/cmd/column-definition.js +145 -47
- package/dist/node_modules/mariadb/lib/cmd/command.js +41 -75
- package/dist/node_modules/mariadb/lib/cmd/decoder/binary-decoder.js +282 -0
- package/dist/node_modules/mariadb/lib/cmd/decoder/text-decoder.js +210 -0
- package/dist/node_modules/mariadb/lib/cmd/{common-binary-cmd.js → encoder/binary-encoder.js} +34 -77
- package/dist/node_modules/mariadb/lib/cmd/encoder/text-encoder.js +311 -0
- package/dist/node_modules/mariadb/lib/cmd/execute-stream.js +61 -0
- package/dist/node_modules/mariadb/lib/cmd/execute.js +338 -0
- package/dist/node_modules/mariadb/lib/cmd/handshake/auth/caching-sha2-password-auth.js +25 -62
- package/dist/node_modules/mariadb/lib/cmd/handshake/auth/clear-password-auth.js +39 -6
- package/dist/node_modules/mariadb/lib/cmd/handshake/auth/ed25519-password-auth.js +48 -16
- package/dist/node_modules/mariadb/lib/cmd/handshake/auth/handshake.js +198 -0
- package/dist/node_modules/mariadb/lib/cmd/handshake/{initial-handshake.js → auth/initial-handshake.js} +10 -8
- package/dist/node_modules/mariadb/lib/cmd/handshake/auth/native-password-auth.js +22 -9
- package/dist/node_modules/mariadb/lib/cmd/handshake/auth/pam-password-auth.js +9 -4
- package/dist/node_modules/mariadb/lib/cmd/handshake/auth/parsec-auth.js +115 -0
- package/dist/node_modules/mariadb/lib/cmd/handshake/auth/plugin-auth.js +12 -5
- package/dist/node_modules/mariadb/lib/cmd/handshake/auth/sha256-password-auth.js +44 -33
- package/dist/node_modules/mariadb/lib/cmd/handshake/authentication.js +335 -0
- package/dist/node_modules/mariadb/lib/cmd/handshake/client-capabilities.js +20 -19
- package/dist/node_modules/mariadb/lib/cmd/handshake/ssl-request.js +6 -3
- package/dist/node_modules/mariadb/lib/cmd/parser.js +861 -0
- package/dist/node_modules/mariadb/lib/cmd/ping.js +17 -18
- package/dist/node_modules/mariadb/lib/cmd/prepare.js +170 -0
- package/dist/node_modules/mariadb/lib/cmd/query.js +281 -144
- package/dist/node_modules/mariadb/lib/cmd/quit.js +9 -6
- package/dist/node_modules/mariadb/lib/cmd/reset.js +15 -19
- package/dist/node_modules/mariadb/lib/cmd/stream.js +21 -6
- package/dist/node_modules/mariadb/lib/config/cluster-options.js +23 -0
- package/dist/node_modules/mariadb/lib/config/connection-options.js +196 -132
- package/dist/node_modules/mariadb/lib/config/pool-options.js +27 -19
- package/dist/node_modules/mariadb/lib/connection-callback.js +492 -120
- package/dist/node_modules/mariadb/lib/connection-promise.js +372 -0
- package/dist/node_modules/mariadb/lib/connection.js +1739 -1016
- package/dist/node_modules/mariadb/lib/const/capabilities.js +36 -30
- package/dist/node_modules/mariadb/lib/const/collations.js +972 -36
- package/dist/node_modules/mariadb/lib/const/connection_status.js +3 -0
- package/dist/node_modules/mariadb/lib/const/error-code.js +35 -11
- package/dist/node_modules/mariadb/lib/const/field-detail.js +3 -0
- package/dist/node_modules/mariadb/lib/const/field-type.js +7 -4
- package/dist/node_modules/mariadb/lib/const/server-status.js +4 -1
- package/dist/node_modules/mariadb/lib/const/state-change.js +3 -0
- package/dist/node_modules/mariadb/lib/filtered-cluster-callback.js +136 -0
- package/dist/node_modules/mariadb/lib/filtered-cluster.js +118 -0
- package/dist/node_modules/mariadb/lib/io/compression-input-stream.js +14 -13
- package/dist/node_modules/mariadb/lib/io/compression-output-stream.js +21 -18
- package/dist/node_modules/mariadb/lib/io/packet-input-stream.js +75 -64
- package/dist/node_modules/mariadb/lib/io/packet-node-encoded.js +13 -9
- package/dist/node_modules/mariadb/lib/io/packet-node-iconv.js +12 -10
- package/dist/node_modules/mariadb/lib/io/packet-output-stream.js +402 -134
- package/dist/node_modules/mariadb/lib/io/packet.js +287 -202
- package/dist/node_modules/mariadb/lib/lru-prepare-cache.js +84 -0
- package/dist/node_modules/mariadb/lib/misc/connection-information.js +15 -32
- package/dist/node_modules/mariadb/lib/misc/errors.js +68 -25
- package/dist/node_modules/mariadb/lib/misc/parse.js +207 -711
- package/dist/node_modules/mariadb/lib/misc/utils.js +34 -62
- package/dist/node_modules/mariadb/lib/pool-callback.js +213 -174
- package/dist/node_modules/mariadb/lib/pool-promise.js +228 -94
- package/dist/node_modules/mariadb/lib/pool.js +951 -0
- package/dist/node_modules/mariadb/package.json +1 -1
- package/dist/node_modules/mariadb/promise.js +1 -34
- package/dist/node_modules/mariadb/types/callback.d.ts +207 -0
- package/dist/node_modules/mariadb/types/index.d.ts +94 -674
- package/dist/node_modules/mariadb/types/share.d.ts +804 -0
- package/dist/node_modules/qs/package.json +1 -1
- package/dist/server/actions/apps.js +2 -2
- package/dist/server/app-lifecycle.d.ts +1 -1
- package/dist/server/app-lifecycle.js +4 -4
- package/dist/server/models/application.d.ts +1 -1
- package/package.json +7 -7
- package/server.d.ts +2 -2
- package/server.js +1 -1
- package/dist/node_modules/mariadb/lib/cmd/batch-rewrite.js +0 -372
- package/dist/node_modules/mariadb/lib/cmd/common-text-cmd.js +0 -427
- package/dist/node_modules/mariadb/lib/cmd/handshake/client-handshake-response.js +0 -126
- package/dist/node_modules/mariadb/lib/cmd/handshake/handshake.js +0 -292
- package/dist/node_modules/mariadb/lib/cmd/resultset.js +0 -607
- package/dist/node_modules/mariadb/lib/config/pool-cluster-options.js +0 -19
- package/dist/node_modules/mariadb/lib/filtered-pool-cluster.js +0 -81
- package/dist/node_modules/mariadb/lib/io/bulk-packet.js +0 -590
- package/dist/node_modules/mariadb/lib/io/rewrite-packet.js +0 -481
- package/dist/node_modules/mariadb/lib/pool-base.js +0 -611
- package/dist/node_modules/mariadb/lib/pool-cluster-callback.js +0 -66
- package/dist/node_modules/mariadb/lib/pool-cluster.js +0 -407
|
@@ -1,611 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const EventEmitter = require('events');
|
|
4
|
-
const util = require('util');
|
|
5
|
-
const Queue = require('denque');
|
|
6
|
-
const Errors = require('./misc/errors');
|
|
7
|
-
const Utils = require('./misc/utils');
|
|
8
|
-
|
|
9
|
-
function PoolBase(options, processTask, createConnectionPool, pingPromise) {
|
|
10
|
-
//*****************************************************************
|
|
11
|
-
// public methods
|
|
12
|
-
//*****************************************************************
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Retrieve a connection from pool.
|
|
16
|
-
* Create a new one, if limit is not reached.
|
|
17
|
-
* wait until acquireTimeout.
|
|
18
|
-
*
|
|
19
|
-
* @return {Promise}
|
|
20
|
-
*/
|
|
21
|
-
this.getConnection = function () {
|
|
22
|
-
return addRequest(this);
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Execute a query on one connection from pool.
|
|
27
|
-
*
|
|
28
|
-
* @param sql sql command
|
|
29
|
-
* @param value parameter value of sql command (not mandatory)
|
|
30
|
-
* @return {Promise}
|
|
31
|
-
*/
|
|
32
|
-
this.query = function (sql, value) {
|
|
33
|
-
return addRequest(this, sql, value, false);
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Execute a batch on one connection from pool.
|
|
38
|
-
*
|
|
39
|
-
* @param sql sql command
|
|
40
|
-
* @param value parameter value of sql command (not mandatory)
|
|
41
|
-
* @return {Promise}
|
|
42
|
-
*/
|
|
43
|
-
this.batch = function (sql, value) {
|
|
44
|
-
return addRequest(this, sql, value, true);
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Close all connection in pool
|
|
49
|
-
*
|
|
50
|
-
* @return Promise
|
|
51
|
-
*/
|
|
52
|
-
this.end = function () {
|
|
53
|
-
if (closed) {
|
|
54
|
-
return Promise.reject(
|
|
55
|
-
Errors.createError(
|
|
56
|
-
'pool is already closed',
|
|
57
|
-
null,
|
|
58
|
-
false,
|
|
59
|
-
null,
|
|
60
|
-
'HY000',
|
|
61
|
-
Errors.ER_POOL_ALREADY_CLOSED,
|
|
62
|
-
undefined,
|
|
63
|
-
false
|
|
64
|
-
)
|
|
65
|
-
);
|
|
66
|
-
}
|
|
67
|
-
closed = true;
|
|
68
|
-
clearInterval(idleMaintainingTask);
|
|
69
|
-
|
|
70
|
-
//close unused connections
|
|
71
|
-
const idleConnectionsEndings = [];
|
|
72
|
-
let conn;
|
|
73
|
-
while ((conn = idleConnections.shift())) {
|
|
74
|
-
idleConnectionsEndings.push(conn.forceEnd());
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
firstTaskTimeout = clearTimeout(firstTaskTimeout);
|
|
78
|
-
|
|
79
|
-
//reject all waiting task
|
|
80
|
-
if (taskQueue.size() > 0) {
|
|
81
|
-
let task;
|
|
82
|
-
const err = Errors.createError(
|
|
83
|
-
'pool is ending, connection request aborted',
|
|
84
|
-
null,
|
|
85
|
-
false,
|
|
86
|
-
null,
|
|
87
|
-
'HY000',
|
|
88
|
-
Errors.ER_CLOSING_POOL,
|
|
89
|
-
undefined,
|
|
90
|
-
false
|
|
91
|
-
);
|
|
92
|
-
while ((task = taskQueue.shift())) {
|
|
93
|
-
process.nextTick(task.reject, err);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
return Promise.all(idleConnectionsEndings);
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Get current active connections.
|
|
102
|
-
* @return {number}
|
|
103
|
-
*/
|
|
104
|
-
this.activeConnections = function () {
|
|
105
|
-
return Object.keys(activeConnections).length;
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Get current total connection number.
|
|
110
|
-
* @return {number}
|
|
111
|
-
*/
|
|
112
|
-
this.totalConnections = function () {
|
|
113
|
-
return this.activeConnections() + this.idleConnections();
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* Get current idle connection number.
|
|
118
|
-
* @return {number}
|
|
119
|
-
*/
|
|
120
|
-
this.idleConnections = function () {
|
|
121
|
-
return idleConnections.size();
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Get current stacked connection request.
|
|
126
|
-
* @return {number}
|
|
127
|
-
*/
|
|
128
|
-
this.taskQueueSize = function () {
|
|
129
|
-
return taskQueue.size();
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* First connection creation.
|
|
134
|
-
* activation is slightly different than pooling grow : If connection fails, there is many retries for 30s
|
|
135
|
-
* (option initializationTimeout).
|
|
136
|
-
* If connection fails, error will be thrown to request / console if no request, to ensure that error is thrown.
|
|
137
|
-
*/
|
|
138
|
-
this.initialize = function () {
|
|
139
|
-
connectionInCreation = true;
|
|
140
|
-
const self = this;
|
|
141
|
-
const timeoutEnd = Date.now() + opts.initializationTimeout;
|
|
142
|
-
connectionCreationLoop(self, 0, timeoutEnd)
|
|
143
|
-
.then((conn) => {
|
|
144
|
-
//add to pool
|
|
145
|
-
if (closed) {
|
|
146
|
-
conn.forceEnd().catch((err) => {});
|
|
147
|
-
} else {
|
|
148
|
-
addPoolConnection(self, conn);
|
|
149
|
-
if (opts.idleTimeout > 0) {
|
|
150
|
-
idleMaintainingTask = setInterval(idleMaintainer, 500, self);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
})
|
|
154
|
-
.catch((err) => {
|
|
155
|
-
connectionInCreation = false;
|
|
156
|
-
const task = taskQueue.shift();
|
|
157
|
-
if (task) {
|
|
158
|
-
firstTaskTimeout = clearTimeout(firstTaskTimeout);
|
|
159
|
-
process.nextTick(task.reject, err);
|
|
160
|
-
resetTimeoutToNextTask();
|
|
161
|
-
} else if (!closed) {
|
|
162
|
-
console.error(err);
|
|
163
|
-
}
|
|
164
|
-
})
|
|
165
|
-
.finally(() => {
|
|
166
|
-
ensurePoolSize(self);
|
|
167
|
-
});
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
this.escape = (value) => {
|
|
171
|
-
return Utils.escape(options.connOptions, searchInfo(), value);
|
|
172
|
-
};
|
|
173
|
-
|
|
174
|
-
this.escapeId = (value) => {
|
|
175
|
-
return Utils.escapeId(options.connOptions, searchInfo(), value);
|
|
176
|
-
};
|
|
177
|
-
|
|
178
|
-
//*****************************************************************
|
|
179
|
-
// internal methods
|
|
180
|
-
//*****************************************************************
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* Search info object of an existing connection. to know server type and version.
|
|
184
|
-
* @returns information object if connection available.
|
|
185
|
-
*/
|
|
186
|
-
const searchInfo = () => {
|
|
187
|
-
let info = null;
|
|
188
|
-
let conn = idleConnections.get(0);
|
|
189
|
-
|
|
190
|
-
if (conn == null) {
|
|
191
|
-
conn = Object.keys(activeConnections)[0];
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
if (conn != null) {
|
|
195
|
-
info = conn.info;
|
|
196
|
-
}
|
|
197
|
-
return info;
|
|
198
|
-
};
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Get a connection from pool / execute query
|
|
202
|
-
*
|
|
203
|
-
* @param pool current pool
|
|
204
|
-
* @param sql sql value (not mandatory)
|
|
205
|
-
* @param values sql parameter (not mandatory)
|
|
206
|
-
* @param isBatch is batch request
|
|
207
|
-
* @return {*}
|
|
208
|
-
*/
|
|
209
|
-
const addRequest = function (pool, sql, values, isBatch) {
|
|
210
|
-
if (isBatch != undefined && !sql) {
|
|
211
|
-
// request for query/batch without sql
|
|
212
|
-
return Promise.reject(
|
|
213
|
-
Errors.createError(
|
|
214
|
-
'sql parameter is mandatory',
|
|
215
|
-
null,
|
|
216
|
-
false,
|
|
217
|
-
null,
|
|
218
|
-
'HY000',
|
|
219
|
-
Errors.ER_POOL_UNDEFINED_SQL,
|
|
220
|
-
undefined,
|
|
221
|
-
false
|
|
222
|
-
)
|
|
223
|
-
);
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
if (closed) {
|
|
227
|
-
return Promise.reject(
|
|
228
|
-
Errors.createError(
|
|
229
|
-
'pool is closed',
|
|
230
|
-
null,
|
|
231
|
-
false,
|
|
232
|
-
null,
|
|
233
|
-
'HY000',
|
|
234
|
-
Errors.ER_POOL_ALREADY_CLOSED,
|
|
235
|
-
undefined,
|
|
236
|
-
false
|
|
237
|
-
)
|
|
238
|
-
);
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
return getIdleValidConnection(pool).then(
|
|
242
|
-
(conn) => {
|
|
243
|
-
pool.emit('acquire', conn);
|
|
244
|
-
return processTask(conn, sql, values, isBatch);
|
|
245
|
-
},
|
|
246
|
-
() => {
|
|
247
|
-
process.nextTick(() => pool.emit('enqueue'));
|
|
248
|
-
|
|
249
|
-
//no idle connection available
|
|
250
|
-
//create a new connection if limit is not reached
|
|
251
|
-
ensurePoolSize(pool);
|
|
252
|
-
|
|
253
|
-
//connections are all used, stack demand.
|
|
254
|
-
return new Promise((resolve, reject) => {
|
|
255
|
-
const task = {
|
|
256
|
-
timeout: Date.now() + opts.acquireTimeout,
|
|
257
|
-
reject: reject,
|
|
258
|
-
resolve: resolve,
|
|
259
|
-
sql: sql,
|
|
260
|
-
values: values,
|
|
261
|
-
isBatch: isBatch
|
|
262
|
-
};
|
|
263
|
-
if (!firstTaskTimeout) {
|
|
264
|
-
firstTaskTimeout = setTimeout(rejectAndResetTimeout, opts.acquireTimeout, task);
|
|
265
|
-
}
|
|
266
|
-
taskQueue.push(task);
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
|
-
);
|
|
270
|
-
};
|
|
271
|
-
|
|
272
|
-
/**
|
|
273
|
-
* Return an idle Connection.
|
|
274
|
-
* If connection has not been used for some time ( minDelayValidation), validate connection status.
|
|
275
|
-
*
|
|
276
|
-
* @param pool pool
|
|
277
|
-
* @returns {Promise<Connection|null>)} connection of null of no valid idle connection.
|
|
278
|
-
*/
|
|
279
|
-
const getIdleValidConnection = function (pool) {
|
|
280
|
-
if (idleConnections.isEmpty()) {
|
|
281
|
-
return Promise.reject(null);
|
|
282
|
-
}
|
|
283
|
-
const conn = idleConnections.shift();
|
|
284
|
-
activeConnections[conn.threadId] = conn;
|
|
285
|
-
if (opts.minDelayValidation <= 0 || Date.now() - conn.lastUse > opts.minDelayValidation) {
|
|
286
|
-
return pingPromise(conn)
|
|
287
|
-
.then(() => {
|
|
288
|
-
initLeakProcess(conn);
|
|
289
|
-
return Promise.resolve(conn);
|
|
290
|
-
})
|
|
291
|
-
.catch((err) => {
|
|
292
|
-
delete activeConnections[conn.threadId];
|
|
293
|
-
pool.emit('_remove-conn');
|
|
294
|
-
return getIdleValidConnection(pool);
|
|
295
|
-
});
|
|
296
|
-
} else {
|
|
297
|
-
//just check connection state
|
|
298
|
-
if (conn.isValid()) {
|
|
299
|
-
initLeakProcess(conn);
|
|
300
|
-
return Promise.resolve(conn);
|
|
301
|
-
} else {
|
|
302
|
-
delete activeConnections[conn.threadId];
|
|
303
|
-
pool.emit('_remove-conn');
|
|
304
|
-
return getIdleValidConnection(pool);
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
};
|
|
308
|
-
|
|
309
|
-
/**
|
|
310
|
-
* Task request timeout handler
|
|
311
|
-
* @param task
|
|
312
|
-
*/
|
|
313
|
-
const timeoutTask = (task) => {
|
|
314
|
-
firstTaskTimeout = null;
|
|
315
|
-
if (task === taskQueue.peekFront()) {
|
|
316
|
-
taskQueue.shift();
|
|
317
|
-
process.nextTick(
|
|
318
|
-
task.reject,
|
|
319
|
-
Errors.createError(
|
|
320
|
-
'retrieve connection from pool timeout after ' +
|
|
321
|
-
Math.abs(Date.now() - (task.timeout - opts.acquireTimeout)) +
|
|
322
|
-
'ms',
|
|
323
|
-
null,
|
|
324
|
-
false,
|
|
325
|
-
null,
|
|
326
|
-
'HY000',
|
|
327
|
-
Errors.ER_GET_CONNECTION_TIMEOUT,
|
|
328
|
-
undefined,
|
|
329
|
-
false
|
|
330
|
-
)
|
|
331
|
-
);
|
|
332
|
-
} else {
|
|
333
|
-
throw new Error('Rejection by timeout without task !!!');
|
|
334
|
-
}
|
|
335
|
-
};
|
|
336
|
-
|
|
337
|
-
/**
|
|
338
|
-
* Reject task, and reset timeout to next waiting task if any.
|
|
339
|
-
* @param task
|
|
340
|
-
*/
|
|
341
|
-
const rejectAndResetTimeout = (task) => {
|
|
342
|
-
timeoutTask(task);
|
|
343
|
-
resetTimeoutToNextTask();
|
|
344
|
-
};
|
|
345
|
-
|
|
346
|
-
/**
|
|
347
|
-
* Loop for connection creation.
|
|
348
|
-
* This permits to wait before next try after a connection fail.
|
|
349
|
-
*
|
|
350
|
-
* @param pool current pool
|
|
351
|
-
* @param iteration current iteration
|
|
352
|
-
* @param timeoutEnd ending timeout
|
|
353
|
-
* @returns {Promise<any>} Connection if found, error if not
|
|
354
|
-
*/
|
|
355
|
-
const connectionCreationLoop = function (pool, iteration, timeoutEnd) {
|
|
356
|
-
return new Promise(function (resolve, reject) {
|
|
357
|
-
const creationTryout = function (resolve, reject) {
|
|
358
|
-
if (closed) {
|
|
359
|
-
reject(
|
|
360
|
-
Errors.createError(
|
|
361
|
-
'Cannot create new connection to pool, pool closed',
|
|
362
|
-
null,
|
|
363
|
-
true,
|
|
364
|
-
null,
|
|
365
|
-
'08S01',
|
|
366
|
-
Errors.ER_ADD_CONNECTION_CLOSED_POOL,
|
|
367
|
-
null
|
|
368
|
-
)
|
|
369
|
-
);
|
|
370
|
-
return;
|
|
371
|
-
}
|
|
372
|
-
iteration++;
|
|
373
|
-
createConnectionPool(pool)
|
|
374
|
-
.then((conn) => {
|
|
375
|
-
resolve(conn);
|
|
376
|
-
})
|
|
377
|
-
.catch((err) => {
|
|
378
|
-
//if timeout is reached or authentication fail return error
|
|
379
|
-
if (
|
|
380
|
-
closed ||
|
|
381
|
-
(err.errno && (err.errno === 1524 || err.errno === 1045 || err.errno === 1698)) ||
|
|
382
|
-
timeoutEnd < Date.now()
|
|
383
|
-
) {
|
|
384
|
-
reject(err);
|
|
385
|
-
return;
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
setTimeout(creationTryout.bind(null, resolve, reject), 500);
|
|
389
|
-
});
|
|
390
|
-
};
|
|
391
|
-
//initial without timeout
|
|
392
|
-
creationTryout(resolve, reject);
|
|
393
|
-
});
|
|
394
|
-
};
|
|
395
|
-
|
|
396
|
-
const addPoolConnection = function (pool, conn) {
|
|
397
|
-
conn.lastUse = Date.now();
|
|
398
|
-
const initialDestroyFct = conn.destroy;
|
|
399
|
-
conn.destroy = () => {
|
|
400
|
-
removeLeakProcess(conn);
|
|
401
|
-
delete activeConnections[conn.threadId];
|
|
402
|
-
initialDestroyFct();
|
|
403
|
-
pool.emit('_remove-conn');
|
|
404
|
-
};
|
|
405
|
-
|
|
406
|
-
//Connection error
|
|
407
|
-
// -> evict connection from pool
|
|
408
|
-
conn.on('error', (err) => {
|
|
409
|
-
let idx = 0;
|
|
410
|
-
let currConn;
|
|
411
|
-
removeLeakProcess(conn);
|
|
412
|
-
delete activeConnections[conn.threadId];
|
|
413
|
-
while ((currConn = idleConnections.peekAt(idx))) {
|
|
414
|
-
if (currConn === conn) {
|
|
415
|
-
idleConnections.removeOne(idx);
|
|
416
|
-
break;
|
|
417
|
-
} else {
|
|
418
|
-
//since connection did have an error, other waiting connection might too
|
|
419
|
-
//forcing validation when borrowed next time, even if "minDelayValidation" is not reached.
|
|
420
|
-
currConn.lastUse = Math.min(Date.now() - opts.minDelayValidation, currConn.lastUse);
|
|
421
|
-
}
|
|
422
|
-
idx++;
|
|
423
|
-
}
|
|
424
|
-
pool.emit('_remove-conn');
|
|
425
|
-
});
|
|
426
|
-
connectionInCreation = false;
|
|
427
|
-
idleConnections.push(conn);
|
|
428
|
-
pool.emit('_idle-conn');
|
|
429
|
-
process.nextTick(() => pool.emit('connection', conn));
|
|
430
|
-
};
|
|
431
|
-
|
|
432
|
-
this._releaseConnection = function (conn) {
|
|
433
|
-
removeLeakProcess(conn);
|
|
434
|
-
conn.lastUse = Date.now();
|
|
435
|
-
delete activeConnections[conn.threadId];
|
|
436
|
-
const pool = this;
|
|
437
|
-
if (closed) {
|
|
438
|
-
return conn.forceEnd().catch(() => {
|
|
439
|
-
return Promise.resolve();
|
|
440
|
-
});
|
|
441
|
-
} else if (conn.isValid()) {
|
|
442
|
-
pool.emit('release', conn);
|
|
443
|
-
idleConnections.push(conn);
|
|
444
|
-
process.nextTick(() => pool.emit('_idle-conn'));
|
|
445
|
-
} else {
|
|
446
|
-
ensurePoolSize(pool);
|
|
447
|
-
}
|
|
448
|
-
};
|
|
449
|
-
|
|
450
|
-
/**
|
|
451
|
-
* Grow pool connections until reaching connection limit.
|
|
452
|
-
*/
|
|
453
|
-
const ensurePoolSize = function (pool) {
|
|
454
|
-
if (
|
|
455
|
-
!connectionInCreation &&
|
|
456
|
-
pool.idleConnections() < opts.minimumIdle &&
|
|
457
|
-
pool.totalConnections() < opts.connectionLimit &&
|
|
458
|
-
!closed
|
|
459
|
-
) {
|
|
460
|
-
connectionInCreation = true;
|
|
461
|
-
process.nextTick(() => {
|
|
462
|
-
const timeoutEnd = Date.now() + opts.initializationTimeout;
|
|
463
|
-
if (!closed) {
|
|
464
|
-
connectionCreationLoop(pool, 0, timeoutEnd)
|
|
465
|
-
.then((conn) => {
|
|
466
|
-
if (closed) {
|
|
467
|
-
return conn.forceEnd().catch((err) => {});
|
|
468
|
-
}
|
|
469
|
-
addPoolConnection(pool, conn);
|
|
470
|
-
})
|
|
471
|
-
.catch((err) => {
|
|
472
|
-
if (pool.totalConnections() === 0) {
|
|
473
|
-
const task = taskQueue.shift();
|
|
474
|
-
if (task) {
|
|
475
|
-
firstTaskTimeout = clearTimeout(firstTaskTimeout);
|
|
476
|
-
process.nextTick(task.reject, err);
|
|
477
|
-
resetTimeoutToNextTask();
|
|
478
|
-
}
|
|
479
|
-
} else if (!closed) {
|
|
480
|
-
console.error(`pool fail to create connection (${err.message})`);
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
//delay next try
|
|
484
|
-
setTimeout(() => {
|
|
485
|
-
connectionInCreation = false;
|
|
486
|
-
if (taskQueue.size() > 0) {
|
|
487
|
-
ensurePoolSize(pool);
|
|
488
|
-
}
|
|
489
|
-
}, 500);
|
|
490
|
-
});
|
|
491
|
-
}
|
|
492
|
-
});
|
|
493
|
-
}
|
|
494
|
-
};
|
|
495
|
-
|
|
496
|
-
const resetTimeoutToNextTask = () => {
|
|
497
|
-
//handle next Timer
|
|
498
|
-
const currTime = Date.now();
|
|
499
|
-
let nextTask;
|
|
500
|
-
while ((nextTask = taskQueue.peekFront())) {
|
|
501
|
-
if (nextTask.timeout < currTime) {
|
|
502
|
-
timeoutTask(nextTask);
|
|
503
|
-
} else {
|
|
504
|
-
firstTaskTimeout = setTimeout(rejectAndResetTimeout, nextTask.timeout - currTime, nextTask);
|
|
505
|
-
return;
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
};
|
|
509
|
-
|
|
510
|
-
/**
|
|
511
|
-
* Permit to remove idle connection if unused for some time.
|
|
512
|
-
* @param pool current pool
|
|
513
|
-
*/
|
|
514
|
-
const idleMaintainer = function (pool) {
|
|
515
|
-
let toRemove = Math.max(1, pool.idleConnections() - opts.minimumIdle);
|
|
516
|
-
while (toRemove > 0) {
|
|
517
|
-
const conn = idleConnections.peek();
|
|
518
|
-
--toRemove;
|
|
519
|
-
if (conn && conn.lastUse + opts.idleTimeout * 1000 < Date.now()) {
|
|
520
|
-
idleConnections.shift();
|
|
521
|
-
conn.forceEnd().catch((err) => {});
|
|
522
|
-
continue;
|
|
523
|
-
}
|
|
524
|
-
break;
|
|
525
|
-
}
|
|
526
|
-
ensurePoolSize(pool);
|
|
527
|
-
};
|
|
528
|
-
|
|
529
|
-
this._discardConnection = (conn) => {
|
|
530
|
-
removeLeakProcess(conn);
|
|
531
|
-
delete activeConnections[conn.threadId];
|
|
532
|
-
conn.forceEnd().catch((err) => {});
|
|
533
|
-
this.emit('_remove-conn');
|
|
534
|
-
};
|
|
535
|
-
|
|
536
|
-
const logLeak = (conn) => {
|
|
537
|
-
console.log(
|
|
538
|
-
'Possible connection leak on thread ' +
|
|
539
|
-
conn.info.threadId +
|
|
540
|
-
' (connection not returned to pool since ' +
|
|
541
|
-
(Date.now() - conn.lastUse) +
|
|
542
|
-
'ms. Did connection.released() been implemented'
|
|
543
|
-
);
|
|
544
|
-
conn.leaked = true;
|
|
545
|
-
};
|
|
546
|
-
|
|
547
|
-
const _initLeakProcess = (conn) => {
|
|
548
|
-
conn.lastUse = Date.now();
|
|
549
|
-
conn.leaked = false;
|
|
550
|
-
conn.leakProcess = setTimeout(logLeak, opts.leakDetectionTimeout, conn);
|
|
551
|
-
};
|
|
552
|
-
|
|
553
|
-
const _removeLeakProcess = (conn) => {
|
|
554
|
-
conn.leakProcess = clearTimeout(conn.leakProcess);
|
|
555
|
-
if (conn.leaked) {
|
|
556
|
-
console.log(
|
|
557
|
-
'Previous possible leak connection with thread ' +
|
|
558
|
-
conn.info.threadId +
|
|
559
|
-
' was returned to pool'
|
|
560
|
-
);
|
|
561
|
-
}
|
|
562
|
-
};
|
|
563
|
-
|
|
564
|
-
/**
|
|
565
|
-
* Launch next waiting task request if available connections.
|
|
566
|
-
*/
|
|
567
|
-
const handleTaskQueue = function () {
|
|
568
|
-
firstTaskTimeout = clearTimeout(firstTaskTimeout);
|
|
569
|
-
const task = taskQueue.shift();
|
|
570
|
-
|
|
571
|
-
if (task) {
|
|
572
|
-
const conn = idleConnections.shift();
|
|
573
|
-
if (conn) {
|
|
574
|
-
initLeakProcess(conn);
|
|
575
|
-
this.emit('acquire', conn);
|
|
576
|
-
activeConnections[conn.threadId] = conn;
|
|
577
|
-
resetTimeoutToNextTask();
|
|
578
|
-
processTask(conn, task.sql, task.values, task.isBatch)
|
|
579
|
-
.then(task.resolve)
|
|
580
|
-
.catch(task.reject);
|
|
581
|
-
} else {
|
|
582
|
-
taskQueue.unshift(task);
|
|
583
|
-
}
|
|
584
|
-
}
|
|
585
|
-
};
|
|
586
|
-
|
|
587
|
-
const opts = options;
|
|
588
|
-
let closed = false;
|
|
589
|
-
let connectionInCreation = false;
|
|
590
|
-
const initLeakProcess = opts.leakDetectionTimeout > 0 ? _initLeakProcess : () => {};
|
|
591
|
-
const removeLeakProcess = opts.leakDetectionTimeout > 0 ? _removeLeakProcess : () => {};
|
|
592
|
-
const idleConnections = new Queue();
|
|
593
|
-
const activeConnections = {};
|
|
594
|
-
const taskQueue = new Queue();
|
|
595
|
-
let idleMaintainingTask;
|
|
596
|
-
let firstTaskTimeout;
|
|
597
|
-
Object.defineProperty(this, 'closed', {
|
|
598
|
-
get() {
|
|
599
|
-
return closed;
|
|
600
|
-
}
|
|
601
|
-
});
|
|
602
|
-
|
|
603
|
-
EventEmitter.call(this);
|
|
604
|
-
|
|
605
|
-
this.on('_idle-conn', handleTaskQueue.bind(this));
|
|
606
|
-
this.on('_remove-conn', ensurePoolSize.bind(this, this));
|
|
607
|
-
this.on('connection', ensurePoolSize.bind(this, this));
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
util.inherits(PoolBase, EventEmitter);
|
|
611
|
-
module.exports = PoolBase;
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const PoolCluster = require('./pool-cluster');
|
|
4
|
-
const util = require('util');
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Create a new Cluster.
|
|
8
|
-
* Cluster handle pools with patterns and handle failover / distributed load
|
|
9
|
-
* according to selectors (round robin / random / ordered )
|
|
10
|
-
*
|
|
11
|
-
* @param args cluster argurments. see pool-cluster-options.
|
|
12
|
-
* @constructor
|
|
13
|
-
*/
|
|
14
|
-
function PoolClusterCallback(args) {
|
|
15
|
-
PoolCluster.call(this, args);
|
|
16
|
-
this.setCallback();
|
|
17
|
-
|
|
18
|
-
const initialGetConnection = this.getConnection.bind(this);
|
|
19
|
-
const initialEnd = this.end.bind(this);
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* End cluster (and underlying pools).
|
|
23
|
-
*
|
|
24
|
-
* @param callback - not mandatory
|
|
25
|
-
*/
|
|
26
|
-
this.end = (callback) => {
|
|
27
|
-
if (callback && typeof callback !== 'function') {
|
|
28
|
-
throw new Error('callback parameter must be a function');
|
|
29
|
-
}
|
|
30
|
-
const endingFct = callback ? callback : () => {};
|
|
31
|
-
|
|
32
|
-
initialEnd()
|
|
33
|
-
.then(() => {
|
|
34
|
-
endingFct();
|
|
35
|
-
})
|
|
36
|
-
.catch(endingFct);
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Get connection from available pools matching pattern, according to selector
|
|
41
|
-
*
|
|
42
|
-
* @param pattern pattern filter (not mandatory)
|
|
43
|
-
* @param selector node selector ('RR','RANDOM' or 'ORDER')
|
|
44
|
-
* @param callback callback function
|
|
45
|
-
*/
|
|
46
|
-
this.getConnection = (pattern, selector, callback) => {
|
|
47
|
-
let pat = pattern,
|
|
48
|
-
sel = selector,
|
|
49
|
-
cal = callback;
|
|
50
|
-
if (typeof pattern === 'function') {
|
|
51
|
-
pat = null;
|
|
52
|
-
sel = null;
|
|
53
|
-
cal = pattern;
|
|
54
|
-
} else if (typeof selector === 'function') {
|
|
55
|
-
sel = null;
|
|
56
|
-
cal = selector;
|
|
57
|
-
}
|
|
58
|
-
const endingFct = cal ? cal : (conn) => {};
|
|
59
|
-
|
|
60
|
-
initialGetConnection(pat, sel, endingFct);
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
util.inherits(PoolClusterCallback, PoolCluster);
|
|
65
|
-
|
|
66
|
-
module.exports = PoolClusterCallback;
|