orange-orm 4.5.0-beta.1 → 4.5.0-beta.3
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 +21 -1
- package/package.json +3 -3
- package/src/applyPatch.js +12 -5
- package/src/client/index.mjs +13529 -6469
- package/src/client/rollup.config.js +24 -4
- package/src/client/stringify.js +2 -9
- package/src/createDomain.js +2 -18
- package/src/d1/newPool.js +1 -1
- package/src/d1/newTransaction.js +1 -0
- package/src/d1/pool/newGenericPool.js +1 -14
- package/src/format.js +9 -0
- package/src/generic-pool.js +274 -313
- package/src/getManyDto.js +52 -21
- package/src/hostExpress/executePath.js +2 -1
- package/src/hostExpress.js +2 -7
- package/src/hostLocal.js +1 -1
- package/src/index.js +2 -1
- package/src/indexBrowser.js +39 -0
- package/src/mssql/newPool.js +1 -1
- package/src/mssql/pool/newGenericPool.js +0 -12
- package/src/mySql/deleteFromSql.js +4 -4
- package/src/mySql/newPool.js +1 -1
- package/src/mySql/pool/newGenericPool.js +0 -12
- package/src/newId.js +2 -1
- package/src/oracle/deleteFromSql.js +4 -4
- package/src/oracle/newInsertCommandCore.js +2 -2
- package/src/oracle/newPool.js +1 -1
- package/src/oracle/pool/newGenericPool.js +0 -12
- package/src/package.json +5 -0
- package/src/pg/deleteFromSql.js +4 -4
- package/src/pg/newPool.js +1 -1
- package/src/pg/pool/newPgPool.js +0 -12
- package/src/promisify.js +24 -0
- package/src/sap/deleteFromSql.js +2 -2
- package/src/sap/newPool.js +1 -1
- package/src/sqlite/deleteFromSql.js +4 -4
- package/src/sqlite/newPool.js +1 -1
- package/src/sqlite/pool/newGenericPool.js +0 -13
- package/src/table/column/negotiateRawSqlFilter.js +1 -72
- package/src/table/column/newBoolean.js +2 -53
- package/src/table/column/utils.js +113 -0
- package/src/table/column.js +6 -2
- package/src/table/commands/newDeleteCommand.js +1 -6
- package/src/table/commands/newInsertCommand.js +5 -2
- package/src/table/commands/newInsertCommandCore.js +11 -11
- package/src/table/deleteSessionContext.js +0 -3
- package/src/table/executeQueries/resolveExecuteQuery.js +0 -7
- package/src/table/newCascadeDeleteStrategy.js +1 -7
- package/src/table/newRelatedTable.js +4 -10
- package/src/table/query/newParameterized.js +8 -11
- package/src/table/query/singleQuery/columnSql/joinLegToColumnSql.js +2 -15
- package/src/table/query/singleQuery/columnSql/newJoinedColumnSql.js +2 -25
- package/src/table/query/singleQuery/columnSql/sharedJoinUtils.js +37 -0
- package/src/table/query/singleQuery/joinSql/joinLegToJoinSql.js +1 -6
- package/src/table/query/singleQuery/joinSql/oneLegToJoinSql.js +1 -7
- package/src/table/query/singleQuery/newJoinSql.js +4 -4
- package/src/table/relatedTable/aggregate.js +0 -6
- package/src/table/relatedTable/all.js +1 -7
- package/src/table/relatedTable/any.js +1 -8
- package/src/table/relatedTable/none.js +1 -7
- package/src/table/relatedTable/where.js +0 -6
- package/src/table/relation/newManyCache.js +11 -3
- package/src/table/resultToRows/dbRowToRow.js +2 -9
- package/src/table/resultToRows/delete/removeFromCache.js +2 -9
- package/src/table/resultToRows/newDecodeDbRow.js +0 -7
- package/src/table/resultToRows/toDto/extractStrategy.js +1 -7
- package/src/table/tryGetSessionContext.js +0 -5
- package/src/table.js +0 -4
- package/src/tedious/deleteFromSql.js +4 -4
- package/src/tedious/getManyDto/newQueryCore.js +1 -1
- package/src/tedious/getManyDto/query/newSubQueries/joinLegToQuery.js +2 -3
- package/src/tedious/getManyDto/query/newSubQueries/manyLegToQuery.js +2 -3
- package/src/tedious/getManyDto/query/newSubQueries/oneLegToQuery.js +13 -14
- package/src/tedious/getManyDto/query/newSubQueries.js +8 -25
- package/src/tedious/newPool.js +1 -1
- package/src/tedious/pool/newGenericPool.js +0 -12
- package/src/validateDeleteConflict.js +11 -5
- package/src/createDomain/negotiateForwardProperty.js +0 -23
- package/src/table/createJSONReadStream.js +0 -7
- package/src/table/createJSONReadStreamDefault.js +0 -33
- package/src/table/createJSONReadStreamNative.js +0 -31
- package/src/table/createReadStream.js +0 -24
- package/src/table/createReadStreamCoreNative.js +0 -40
- package/src/table/createReadStreamDefault.js +0 -102
- package/src/table/createReadStreamNative.js +0 -17
- package/src/table/readStream/extractLimit.js +0 -7
- package/src/table/readStream/extractOrderBy.js +0 -59
- package/src/table/readStream/mySql/newQuery.js +0 -16
- package/src/table/readStream/mySql/query/newSingleQuery.js +0 -21
- package/src/table/readStream/mySql/query/newSubQueries/joinLegToQuery.js +0 -20
- package/src/table/readStream/mySql/query/newSubQueries/manyLegToQuery.js +0 -22
- package/src/table/readStream/mySql/query/newSubQueries/newQueryCore.js +0 -9
- package/src/table/readStream/mySql/query/newSubQueries/newSingleQueryCore.js +0 -18
- package/src/table/readStream/mySql/query/newSubQueries/oneLegToQuery.js +0 -22
- package/src/table/readStream/mySql/query/newSubQueries.js +0 -47
- package/src/table/readStream/mySql/query/singleQuery/newShallowColumnSql.js +0 -18
- package/src/table/readStream/newQuery.js +0 -32
- package/src/table/readStream/newQueryStream.js +0 -8
- package/src/table/readStream/pg/newQuery.js +0 -8
- package/src/table/readStream/pg/newQueryCore.js +0 -17
- package/src/table/readStream/pg/query/newSingleQuery.js +0 -19
- package/src/table/readStream/pg/query/newSubQueries/joinLegToQuery.js +0 -19
- package/src/table/readStream/pg/query/newSubQueries/manyLegToQuery.js +0 -22
- package/src/table/readStream/pg/query/newSubQueries/oneLegToQuery.js +0 -19
- package/src/table/readStream/pg/query/newSubQueries.js +0 -47
- package/src/table/readStream/pg/query/singleQuery/newShallowColumnSql.js +0 -20
- package/src/table/readStreamDefault/createBatchFilter.js +0 -39
- package/src/useHook.js +0 -9
package/src/generic-pool.js
CHANGED
|
@@ -1,27 +1,39 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-this-alias */
|
|
2
|
-
|
|
3
|
-
// @ts-nocheck
|
|
4
|
-
//Taken from https://raw.githubusercontent.com/coopernurse/node-pool/6c98fa9163bbe35b683ffc2b55ac741d02956096/lib/generic-pool.js
|
|
5
|
-
//Version 3 of generic-pool has lots og bugs and node program will never finish.
|
|
6
|
-
//So I copied version 2.5.4 below
|
|
2
|
+
/* @ts-nocheck */
|
|
7
3
|
|
|
8
4
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
5
|
+
* A helper function to schedule a callback in a cross-platform manner:
|
|
6
|
+
* - Uses setImmediate if available (Node).
|
|
7
|
+
* - Else uses queueMicrotask if available (Deno, modern browsers).
|
|
8
|
+
* - Else falls back to setTimeout(fn, 0).
|
|
11
9
|
*/
|
|
10
|
+
function queueTask(fn) {
|
|
11
|
+
if (typeof setImmediate === 'function') {
|
|
12
|
+
setImmediate(fn);
|
|
13
|
+
}
|
|
14
|
+
else if
|
|
15
|
+
(typeof queueMicrotask === 'function') {
|
|
16
|
+
queueMicrotask(fn);
|
|
17
|
+
} else {
|
|
18
|
+
setTimeout(fn, 0);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @class
|
|
24
|
+
* @private
|
|
25
|
+
*/
|
|
12
26
|
function PriorityQueue(size) {
|
|
13
27
|
if (!(this instanceof PriorityQueue)) {
|
|
14
|
-
return new PriorityQueue();
|
|
28
|
+
return new PriorityQueue(size);
|
|
15
29
|
}
|
|
16
30
|
|
|
17
|
-
this._size = size;
|
|
18
|
-
this._slots =
|
|
31
|
+
this._size = Math.max(+size | 0, 1);
|
|
32
|
+
this._slots = [];
|
|
19
33
|
this._total = null;
|
|
20
34
|
|
|
21
35
|
// initialize arrays to hold queue elements
|
|
22
|
-
|
|
23
|
-
this._slots = [];
|
|
24
|
-
for (var i = 0; i < size; i += 1) {
|
|
36
|
+
for (let i = 0; i < this._size; i += 1) {
|
|
25
37
|
this._slots.push([]);
|
|
26
38
|
}
|
|
27
39
|
}
|
|
@@ -29,7 +41,7 @@ function PriorityQueue(size) {
|
|
|
29
41
|
PriorityQueue.prototype.size = function size() {
|
|
30
42
|
if (this._total === null) {
|
|
31
43
|
this._total = 0;
|
|
32
|
-
for (
|
|
44
|
+
for (let i = 0; i < this._size; i += 1) {
|
|
33
45
|
this._total += this._slots[i].length;
|
|
34
46
|
}
|
|
35
47
|
}
|
|
@@ -37,30 +49,22 @@ PriorityQueue.prototype.size = function size() {
|
|
|
37
49
|
};
|
|
38
50
|
|
|
39
51
|
PriorityQueue.prototype.enqueue = function enqueue(obj, priority) {
|
|
40
|
-
var priorityOrig;
|
|
41
|
-
|
|
42
52
|
// Convert to integer with a default value of 0.
|
|
43
53
|
priority = priority && +priority | 0 || 0;
|
|
44
|
-
|
|
45
|
-
// Clear cache for total.
|
|
46
54
|
this._total = null;
|
|
47
|
-
if (priority) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
console.error('invalid priority: ' + priorityOrig + ' must be between 0 and ' + priority);
|
|
53
|
-
}
|
|
55
|
+
if (priority < 0 || priority >= this._size) {
|
|
56
|
+
console.error(
|
|
57
|
+
'invalid priority: ' + priority + ' must be between 0 and ' + (this._size - 1)
|
|
58
|
+
);
|
|
59
|
+
priority = this._size - 1; // put obj at the end of the line
|
|
54
60
|
}
|
|
55
|
-
|
|
56
61
|
this._slots[priority].push(obj);
|
|
57
62
|
};
|
|
58
63
|
|
|
59
|
-
PriorityQueue.prototype.dequeue = function dequeue(
|
|
60
|
-
|
|
61
|
-
// Clear cache for total.
|
|
64
|
+
PriorityQueue.prototype.dequeue = function dequeue() {
|
|
65
|
+
let obj = null;
|
|
62
66
|
this._total = null;
|
|
63
|
-
for (
|
|
67
|
+
for (let i = 0, sl = this._slots.length; i < sl; i += 1) {
|
|
64
68
|
if (this._slots[i].length) {
|
|
65
69
|
obj = this._slots[i].shift();
|
|
66
70
|
break;
|
|
@@ -70,7 +74,7 @@ PriorityQueue.prototype.dequeue = function dequeue(_callback) {
|
|
|
70
74
|
};
|
|
71
75
|
|
|
72
76
|
function doWhileAsync(conditionFn, iterateFn, callbackFn) {
|
|
73
|
-
|
|
77
|
+
const next = function() {
|
|
74
78
|
if (conditionFn()) {
|
|
75
79
|
iterateFn(next);
|
|
76
80
|
} else {
|
|
@@ -81,57 +85,29 @@ function doWhileAsync(conditionFn, iterateFn, callbackFn) {
|
|
|
81
85
|
}
|
|
82
86
|
|
|
83
87
|
/**
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
* as its second argument, that should be called with a single
|
|
104
|
-
* boolean argument being true if the item is still valid and false
|
|
105
|
-
* if it should be removed from pool. Called before item is
|
|
106
|
-
* acquired from pool. Only one of validate/validateAsync may be specified
|
|
107
|
-
* @param {Number} factory.max
|
|
108
|
-
* Maximum number of items that can exist at the same time. Default: 1.
|
|
109
|
-
* Any further acquire requests will be pushed to the waiting list.
|
|
110
|
-
* @param {Number} factory.min
|
|
111
|
-
* Minimum number of items in pool (including in-use). Default: 0.
|
|
112
|
-
* When the pool is created, or a resource destroyed, this minimum will
|
|
113
|
-
* be checked. If the pool resource count is below the minimum, a new
|
|
114
|
-
* resource will be created and added to the pool.
|
|
115
|
-
* @param {Number} factory.idleTimeoutMillis
|
|
116
|
-
* Delay in milliseconds after the idle items in the pool will be destroyed.
|
|
117
|
-
* And idle item is that is not acquired yet. Waiting items doesn't count here.
|
|
118
|
-
* @param {Number} factory.reapIntervalMillis
|
|
119
|
-
* Cleanup is scheduled in every `factory.reapIntervalMillis` milliseconds.
|
|
120
|
-
* @param {Boolean|Function} factory.log
|
|
121
|
-
* Whether the pool should log activity. If function is specified,
|
|
122
|
-
* that will be used instead. The function expects the arguments msg, loglevel
|
|
123
|
-
* @param {Number} factory.priorityRange
|
|
124
|
-
* The range from 1 to be treated as a valid priority
|
|
125
|
-
* @param {RefreshIdle} factory.refreshIdle
|
|
126
|
-
* Should idle resources at or below the min threshold be destroyed and recreated every idleTimeoutMillis? Default: true.
|
|
127
|
-
* @param {Bool} [factory.returnToHead=false]
|
|
128
|
-
* Returns released object to head of available objects list
|
|
129
|
-
*/
|
|
88
|
+
* Generate an Object pool with a specified `factory`.
|
|
89
|
+
*
|
|
90
|
+
* @class
|
|
91
|
+
* @param {Object} factory
|
|
92
|
+
* Factory to be used for generating and destroying the items.
|
|
93
|
+
* @param {String} factory.name
|
|
94
|
+
* @param {Function} factory.create
|
|
95
|
+
* @param {Function} factory.destroy
|
|
96
|
+
* @param {Function} factory.validate
|
|
97
|
+
* @param {Function} factory.validateAsync
|
|
98
|
+
* @param {Number} factory.max
|
|
99
|
+
* @param {Number} factory.min
|
|
100
|
+
* @param {Number} factory.idleTimeoutMillis
|
|
101
|
+
* @param {Number} factory.reapIntervalMillis
|
|
102
|
+
* @param {Boolean|Function} factory.log
|
|
103
|
+
* @param {Number} factory.priorityRange
|
|
104
|
+
* @param {Boolean} factory.refreshIdle
|
|
105
|
+
* @param {Boolean} [factory.returnToHead=false]
|
|
106
|
+
*/
|
|
130
107
|
function Pool(factory) {
|
|
131
108
|
if (!(this instanceof Pool)) {
|
|
132
109
|
return new Pool(factory);
|
|
133
110
|
}
|
|
134
|
-
|
|
135
111
|
if (factory.validate && factory.validateAsync) {
|
|
136
112
|
throw new Error('Only one of validate or validateAsync may be specified');
|
|
137
113
|
}
|
|
@@ -148,7 +124,6 @@ function Pool(factory) {
|
|
|
148
124
|
|
|
149
125
|
factory.max = parseInt(factory.max, 10);
|
|
150
126
|
factory.min = parseInt(factory.min, 10);
|
|
151
|
-
|
|
152
127
|
factory.max = Math.max(isNaN(factory.max) ? 1 : factory.max, 1);
|
|
153
128
|
factory.min = Math.min(isNaN(factory.min) ? 0 : factory.min, factory.max - 1);
|
|
154
129
|
|
|
@@ -167,12 +142,12 @@ function Pool(factory) {
|
|
|
167
142
|
}
|
|
168
143
|
|
|
169
144
|
/**
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
Pool.prototype._log = function
|
|
145
|
+
* logs to console or user-defined log function
|
|
146
|
+
* @private
|
|
147
|
+
* @param {string} str
|
|
148
|
+
* @param {string} level
|
|
149
|
+
*/
|
|
150
|
+
Pool.prototype._log = function _log(str, level) {
|
|
176
151
|
if (typeof this._factory.log === 'function') {
|
|
177
152
|
this._factory.log(str, level);
|
|
178
153
|
} else if (this._factory.log) {
|
|
@@ -181,30 +156,30 @@ Pool.prototype._log = function log(str, level) {
|
|
|
181
156
|
};
|
|
182
157
|
|
|
183
158
|
/**
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
159
|
+
* Request the client to be destroyed. The factory's destroy handler
|
|
160
|
+
* will also be called.
|
|
161
|
+
*
|
|
162
|
+
* This should be called within an acquire() block as an alternative to release().
|
|
163
|
+
*
|
|
164
|
+
* @param {Object} obj
|
|
165
|
+
* The acquired item to be destroyed.
|
|
166
|
+
* @param {Function} [cb]
|
|
167
|
+
* Optional. Callback invoked after client is destroyed
|
|
168
|
+
*/
|
|
194
169
|
Pool.prototype.destroy = function destroy(obj, cb) {
|
|
195
170
|
this._count -= 1;
|
|
196
171
|
if (this._count < 0) this._count = 0;
|
|
197
|
-
this._availableObjects = this._availableObjects.filter(function(objWithTimeout) {
|
|
198
|
-
return (objWithTimeout.obj !== obj);
|
|
199
|
-
});
|
|
200
172
|
|
|
201
|
-
this.
|
|
202
|
-
|
|
203
|
-
|
|
173
|
+
this._availableObjects = this._availableObjects.filter(
|
|
174
|
+
(objWithTimeout) => objWithTimeout.obj !== obj
|
|
175
|
+
);
|
|
176
|
+
this._inUseObjects = this._inUseObjects.filter(
|
|
177
|
+
(objInUse) => objInUse !== obj
|
|
178
|
+
);
|
|
204
179
|
|
|
205
180
|
this._factory.destroy(obj, cb);
|
|
206
181
|
|
|
207
|
-
// keep
|
|
182
|
+
// keep compatibility with old interface
|
|
208
183
|
if (this._factory.destroy.length === 1 && cb && typeof cb === 'function') {
|
|
209
184
|
cb();
|
|
210
185
|
}
|
|
@@ -213,40 +188,41 @@ Pool.prototype.destroy = function destroy(obj, cb) {
|
|
|
213
188
|
};
|
|
214
189
|
|
|
215
190
|
/**
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
Pool.prototype._removeIdle = function
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
var refreshIdle = this._factory.refreshIdle;
|
|
225
|
-
var maxRemovable = this._count - this._factory.min;
|
|
226
|
-
var timeout;
|
|
191
|
+
* Checks and removes the available (idle) clients that have timed out.
|
|
192
|
+
* @private
|
|
193
|
+
*/
|
|
194
|
+
Pool.prototype._removeIdle = function _removeIdle() {
|
|
195
|
+
const now = new Date().getTime();
|
|
196
|
+
const refreshIdle = this._factory.refreshIdle;
|
|
197
|
+
const maxRemovable = this._count - this._factory.min;
|
|
198
|
+
const toRemove = [];
|
|
227
199
|
|
|
228
200
|
this._removeIdleScheduled = false;
|
|
229
201
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
this._log(
|
|
237
|
-
|
|
202
|
+
for (let i = 0; i < this._availableObjects.length; i++) {
|
|
203
|
+
const objWithTimeout = this._availableObjects[i];
|
|
204
|
+
if (
|
|
205
|
+
now >= objWithTimeout.timeout &&
|
|
206
|
+
(refreshIdle || toRemove.length < maxRemovable)
|
|
207
|
+
) {
|
|
208
|
+
this._log(
|
|
209
|
+
'removeIdle() destroying obj - now:' +
|
|
210
|
+
now +
|
|
211
|
+
' timeout:' +
|
|
212
|
+
objWithTimeout.timeout,
|
|
213
|
+
'verbose'
|
|
214
|
+
);
|
|
215
|
+
toRemove.push(objWithTimeout.obj);
|
|
238
216
|
}
|
|
239
217
|
}
|
|
240
218
|
|
|
241
|
-
toRemove.forEach(this.destroy
|
|
242
|
-
|
|
243
|
-
// NOTE: we are re-calcing this value because it may have changed
|
|
244
|
-
// after destroying items above
|
|
245
|
-
// Replace the available items with the ones to keep.
|
|
246
|
-
al = this._availableObjects.length;
|
|
219
|
+
toRemove.forEach((obj) => this.destroy(obj));
|
|
247
220
|
|
|
248
|
-
if (
|
|
249
|
-
this._log(
|
|
221
|
+
if (this._availableObjects.length > 0) {
|
|
222
|
+
this._log(
|
|
223
|
+
'this._availableObjects.length=' + this._availableObjects.length,
|
|
224
|
+
'verbose'
|
|
225
|
+
);
|
|
250
226
|
this._scheduleRemoveIdle();
|
|
251
227
|
} else {
|
|
252
228
|
this._log('removeIdle() all objects removed', 'verbose');
|
|
@@ -254,60 +230,61 @@ Pool.prototype._removeIdle = function removeIdle() {
|
|
|
254
230
|
};
|
|
255
231
|
|
|
256
232
|
/**
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
Pool.prototype._scheduleRemoveIdle = function
|
|
262
|
-
var self = this;
|
|
233
|
+
* Schedule removal of idle items in the pool.
|
|
234
|
+
*
|
|
235
|
+
* More schedules cannot run concurrently.
|
|
236
|
+
*/
|
|
237
|
+
Pool.prototype._scheduleRemoveIdle = function _scheduleRemoveIdle() {
|
|
263
238
|
if (!this._removeIdleScheduled) {
|
|
264
239
|
this._removeIdleScheduled = true;
|
|
265
|
-
this._removeIdleTimer = setTimeout(
|
|
266
|
-
|
|
240
|
+
this._removeIdleTimer = setTimeout(() => {
|
|
241
|
+
this._removeIdle();
|
|
267
242
|
}, this._factory.reapInterval);
|
|
268
243
|
}
|
|
269
244
|
};
|
|
270
245
|
|
|
271
246
|
/**
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
Pool.prototype._dispense = function
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
247
|
+
* Try to get a new client to work, and clean up pool unused (idle) items.
|
|
248
|
+
*
|
|
249
|
+
* - If there are available clients waiting, shift the first one out,
|
|
250
|
+
* and call its callback.
|
|
251
|
+
* - If there are no waiting clients, try to create one if it won't exceed
|
|
252
|
+
* the maximum number of clients.
|
|
253
|
+
* - If creating a new client would exceed the maximum, add the client to
|
|
254
|
+
* the wait list.
|
|
255
|
+
* @private
|
|
256
|
+
*/
|
|
257
|
+
Pool.prototype._dispense = function _dispense() {
|
|
258
|
+
const waitingCount = this._waitingClients.size();
|
|
259
|
+
this._log(
|
|
260
|
+
'dispense() clients=' +
|
|
261
|
+
waitingCount +
|
|
262
|
+
' available=' +
|
|
263
|
+
this._availableObjects.length,
|
|
264
|
+
'info'
|
|
265
|
+
);
|
|
289
266
|
|
|
290
267
|
if (waitingCount < 1) {
|
|
291
268
|
return;
|
|
292
269
|
}
|
|
293
270
|
|
|
294
271
|
if (this._factory.validateAsync) {
|
|
295
|
-
doWhileAsync(
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
272
|
+
doWhileAsync(
|
|
273
|
+
() => this._availableObjects.length > 0,
|
|
274
|
+
this._createAsyncValidator(),
|
|
275
|
+
() => {
|
|
276
|
+
if (this._count < this._factory.max) {
|
|
277
|
+
this._createResource();
|
|
278
|
+
}
|
|
302
279
|
}
|
|
303
|
-
|
|
304
|
-
|
|
280
|
+
);
|
|
305
281
|
return;
|
|
306
282
|
}
|
|
307
283
|
|
|
308
284
|
while (this._availableObjects.length > 0) {
|
|
309
285
|
this._log('dispense() - reusing obj', 'verbose');
|
|
310
|
-
objWithTimeout = this._availableObjects[0];
|
|
286
|
+
const objWithTimeout = this._availableObjects[0];
|
|
287
|
+
|
|
311
288
|
if (!this._factory.validate(objWithTimeout.obj)) {
|
|
312
289
|
this.destroy(objWithTimeout.obj);
|
|
313
290
|
continue;
|
|
@@ -315,7 +292,7 @@ Pool.prototype._dispense = function dispense() {
|
|
|
315
292
|
|
|
316
293
|
this._availableObjects.shift();
|
|
317
294
|
this._inUseObjects.push(objWithTimeout.obj);
|
|
318
|
-
clientCb = this._waitingClients.dequeue();
|
|
295
|
+
const clientCb = this._waitingClients.dequeue();
|
|
319
296
|
return clientCb(null, objWithTimeout.obj);
|
|
320
297
|
}
|
|
321
298
|
|
|
@@ -325,203 +302,193 @@ Pool.prototype._dispense = function dispense() {
|
|
|
325
302
|
};
|
|
326
303
|
|
|
327
304
|
Pool.prototype._createAsyncValidator = function _createAsyncValidator() {
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
var objWithTimeout = self._availableObjects.shift();
|
|
333
|
-
self._asyncTestObjects.push(objWithTimeout);
|
|
305
|
+
return (next) => {
|
|
306
|
+
this._log('dispense() - reusing obj', 'verbose');
|
|
307
|
+
const objWithTimeout = this._availableObjects.shift();
|
|
308
|
+
this._asyncTestObjects.push(objWithTimeout);
|
|
334
309
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
310
|
+
this._factory.validateAsync(objWithTimeout.obj, (valid) => {
|
|
311
|
+
const pos = this._asyncTestObjects.indexOf(objWithTimeout);
|
|
312
|
+
this._asyncTestObjects.splice(pos, 1);
|
|
338
313
|
|
|
339
314
|
if (!valid) {
|
|
340
|
-
|
|
315
|
+
this.destroy(objWithTimeout.obj);
|
|
341
316
|
return next();
|
|
342
317
|
}
|
|
343
|
-
if (
|
|
344
|
-
//
|
|
345
|
-
|
|
318
|
+
if (this._waitingClients.size() < 1) {
|
|
319
|
+
// no longer anyone waiting for a resource
|
|
320
|
+
this._addResourceToAvailableObjects(objWithTimeout.obj);
|
|
346
321
|
return;
|
|
347
322
|
}
|
|
348
323
|
|
|
349
|
-
|
|
350
|
-
|
|
324
|
+
this._inUseObjects.push(objWithTimeout.obj);
|
|
325
|
+
const clientCb = this._waitingClients.dequeue();
|
|
351
326
|
clientCb(null, objWithTimeout.obj);
|
|
352
327
|
});
|
|
353
328
|
};
|
|
354
329
|
};
|
|
355
330
|
|
|
356
331
|
/**
|
|
357
|
-
|
|
358
|
-
|
|
332
|
+
* @private
|
|
333
|
+
*/
|
|
359
334
|
Pool.prototype._createResource = function _createResource() {
|
|
360
335
|
this._count += 1;
|
|
361
|
-
this._log(
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
336
|
+
this._log(
|
|
337
|
+
'createResource() - creating obj - count=' +
|
|
338
|
+
this._count +
|
|
339
|
+
' min=' +
|
|
340
|
+
this._factory.min +
|
|
341
|
+
' max=' +
|
|
342
|
+
this._factory.max,
|
|
343
|
+
'verbose'
|
|
344
|
+
);
|
|
345
|
+
|
|
346
|
+
this._factory.create((...args) => {
|
|
347
|
+
let err, obj;
|
|
348
|
+
if (args.length > 1) {
|
|
349
|
+
[err, obj] = args;
|
|
369
350
|
} else {
|
|
370
|
-
err =
|
|
371
|
-
obj =
|
|
351
|
+
err = args[0] instanceof Error ? args[0] : null;
|
|
352
|
+
obj = args[0] instanceof Error ? null : args[0];
|
|
372
353
|
}
|
|
354
|
+
|
|
355
|
+
const clientCb = this._waitingClients.dequeue();
|
|
356
|
+
|
|
373
357
|
if (err) {
|
|
374
|
-
|
|
375
|
-
if (
|
|
358
|
+
this._count -= 1;
|
|
359
|
+
if (this._count < 0) this._count = 0;
|
|
376
360
|
if (clientCb) {
|
|
377
361
|
clientCb(err, obj);
|
|
378
362
|
}
|
|
379
|
-
process.nextTick
|
|
380
|
-
|
|
363
|
+
// queueTask to simulate process.nextTick
|
|
364
|
+
queueTask(() => {
|
|
365
|
+
this._dispense();
|
|
381
366
|
});
|
|
382
367
|
} else {
|
|
383
|
-
|
|
368
|
+
this._inUseObjects.push(obj);
|
|
384
369
|
if (clientCb) {
|
|
385
|
-
clientCb(
|
|
370
|
+
clientCb(null, obj);
|
|
386
371
|
} else {
|
|
387
|
-
|
|
372
|
+
this._addResourceToAvailableObjects(obj);
|
|
388
373
|
}
|
|
389
374
|
}
|
|
390
375
|
});
|
|
391
376
|
};
|
|
392
377
|
|
|
393
378
|
Pool.prototype._addResourceToAvailableObjects = function(obj) {
|
|
394
|
-
|
|
395
|
-
obj
|
|
396
|
-
timeout:
|
|
379
|
+
const objWithTimeout = {
|
|
380
|
+
obj,
|
|
381
|
+
timeout: new Date().getTime() + this._factory.idleTimeoutMillis,
|
|
397
382
|
};
|
|
398
|
-
|
|
399
383
|
if (this._factory.returnToHead) {
|
|
400
|
-
this._availableObjects.
|
|
384
|
+
this._availableObjects.unshift(objWithTimeout);
|
|
401
385
|
} else {
|
|
402
386
|
this._availableObjects.push(objWithTimeout);
|
|
403
387
|
}
|
|
404
|
-
|
|
405
388
|
this._dispense();
|
|
406
389
|
this._scheduleRemoveIdle();
|
|
407
390
|
};
|
|
408
391
|
|
|
409
392
|
/**
|
|
410
|
-
|
|
411
|
-
|
|
393
|
+
* @private
|
|
394
|
+
*/
|
|
412
395
|
Pool.prototype._ensureMinimum = function _ensureMinimum() {
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
for (i = 0; i < diff; i++) {
|
|
396
|
+
if (!this._draining && this._count < this._factory.min) {
|
|
397
|
+
const diff = this._factory.min - this._count;
|
|
398
|
+
for (let i = 0; i < diff; i++) {
|
|
417
399
|
this._createResource();
|
|
418
400
|
}
|
|
419
401
|
}
|
|
420
402
|
};
|
|
421
403
|
|
|
422
404
|
/**
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
* @param {Number} priority
|
|
431
|
-
* Optional. Integer between 0 and (priorityRange - 1). Specifies the priority
|
|
432
|
-
* of the caller if there are no available resources. Lower numbers mean higher
|
|
433
|
-
* priority.
|
|
434
|
-
*
|
|
435
|
-
* @returns {boolean} `true` if the pool is not fully utilized, `false` otherwise.
|
|
436
|
-
*/
|
|
405
|
+
* Request a new client. The callback will be called
|
|
406
|
+
* when a new client is available.
|
|
407
|
+
*
|
|
408
|
+
* @param {Function} callback
|
|
409
|
+
* @param {Number} [priority]
|
|
410
|
+
* @returns {Boolean} true if the pool is not fully utilized, false otherwise
|
|
411
|
+
*/
|
|
437
412
|
Pool.prototype.acquire = function acquire(callback, priority) {
|
|
438
413
|
if (this._draining) {
|
|
439
414
|
throw new Error('pool is draining and cannot accept work');
|
|
440
415
|
}
|
|
441
|
-
if (process.domain) {
|
|
442
|
-
callback = process.domain.bind(callback);
|
|
443
|
-
}
|
|
444
416
|
this._waitingClients.enqueue(callback, priority);
|
|
445
417
|
this._dispense();
|
|
446
|
-
return
|
|
418
|
+
return this._count < this._factory.max;
|
|
447
419
|
};
|
|
448
420
|
|
|
449
421
|
/**
|
|
450
|
-
|
|
451
|
-
|
|
422
|
+
* @deprecated
|
|
423
|
+
*/
|
|
452
424
|
Pool.prototype.borrow = function borrow(callback, priority) {
|
|
453
425
|
this._log('borrow() is deprecated. use acquire() instead', 'warn');
|
|
454
|
-
this.acquire(callback, priority);
|
|
426
|
+
return this.acquire(callback, priority);
|
|
455
427
|
};
|
|
456
428
|
|
|
457
429
|
/**
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
*/
|
|
430
|
+
* Return the client to the pool, indicating it is no longer needed.
|
|
431
|
+
*
|
|
432
|
+
* @param {Object} obj
|
|
433
|
+
*/
|
|
463
434
|
Pool.prototype.release = function release(obj) {
|
|
464
|
-
//
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
435
|
+
// Check whether this object has already been released
|
|
436
|
+
const alreadyReleased = this._availableObjects.some(o => o.obj === obj);
|
|
437
|
+
if (alreadyReleased) {
|
|
438
|
+
this._log(
|
|
439
|
+
'release called twice for the same resource: ' + new Error().stack,
|
|
440
|
+
'error'
|
|
441
|
+
);
|
|
469
442
|
return;
|
|
470
443
|
}
|
|
471
444
|
|
|
472
|
-
//
|
|
473
|
-
|
|
445
|
+
// remove from in-use list
|
|
446
|
+
const index = this._inUseObjects.indexOf(obj);
|
|
474
447
|
if (index < 0) {
|
|
475
|
-
this._log(
|
|
448
|
+
this._log(
|
|
449
|
+
'attempt to release an invalid resource: ' + new Error().stack,
|
|
450
|
+
'error'
|
|
451
|
+
);
|
|
476
452
|
return;
|
|
477
453
|
}
|
|
478
454
|
|
|
479
|
-
// this._log("return to pool")
|
|
480
455
|
this._inUseObjects.splice(index, 1);
|
|
481
456
|
this._addResourceToAvailableObjects(obj);
|
|
482
457
|
};
|
|
483
458
|
|
|
484
459
|
/**
|
|
485
|
-
|
|
486
|
-
|
|
460
|
+
* @deprecated
|
|
461
|
+
*/
|
|
487
462
|
Pool.prototype.returnToPool = function returnToPool(obj) {
|
|
488
463
|
this._log('returnToPool() is deprecated. use release() instead', 'warn');
|
|
489
464
|
this.release(obj);
|
|
490
465
|
};
|
|
491
466
|
|
|
492
467
|
function invoke(cb) {
|
|
493
|
-
|
|
494
|
-
setImmediate(cb);
|
|
495
|
-
} else {
|
|
496
|
-
setTimeout(cb, 0);
|
|
497
|
-
}
|
|
468
|
+
queueTask(cb);
|
|
498
469
|
}
|
|
499
470
|
|
|
500
471
|
/**
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
*/
|
|
472
|
+
* Disallow any new requests and let the request backlog dissipate.
|
|
473
|
+
*
|
|
474
|
+
* @param {Function} [callback]
|
|
475
|
+
* Callback invoked when all work is done and all clients have been released.
|
|
476
|
+
*/
|
|
507
477
|
Pool.prototype.drain = function drain(callback) {
|
|
508
478
|
this._log('draining', 'info');
|
|
509
|
-
|
|
510
|
-
// disable the ability to put more work on the queue.
|
|
511
479
|
this._draining = true;
|
|
512
480
|
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
// wait until all client requests have been satisfied.
|
|
481
|
+
const check = () => {
|
|
482
|
+
if (this._waitingClients.size() > 0) {
|
|
483
|
+
// wait until all client requests have been satisfied
|
|
517
484
|
return setTimeout(check, 100);
|
|
518
485
|
}
|
|
519
|
-
if (
|
|
520
|
-
// wait until
|
|
486
|
+
if (this._asyncTestObjects.length > 0) {
|
|
487
|
+
// wait until async validations are done
|
|
521
488
|
return setTimeout(check, 100);
|
|
522
489
|
}
|
|
523
|
-
if (
|
|
524
|
-
// wait until in
|
|
490
|
+
if (this._availableObjects.length !== this._count) {
|
|
491
|
+
// wait until in-use objects have been released
|
|
525
492
|
return setTimeout(check, 100);
|
|
526
493
|
}
|
|
527
494
|
if (callback) {
|
|
@@ -532,25 +499,22 @@ Pool.prototype.drain = function drain(callback) {
|
|
|
532
499
|
};
|
|
533
500
|
|
|
534
501
|
/**
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
* Optional. Callback invoked after all existing clients are destroyed.
|
|
546
|
-
*/
|
|
502
|
+
* Forcibly destroys all clients regardless of timeout.
|
|
503
|
+
* Does not prevent creation of new clients from subsequent calls to acquire.
|
|
504
|
+
*
|
|
505
|
+
* If factory.min > 0, the pool will destroy all idle resources
|
|
506
|
+
* but replace them with newly created resources up to factory.min.
|
|
507
|
+
* If this is not desired, set factory.min to zero before calling.
|
|
508
|
+
*
|
|
509
|
+
* @param {Function} [callback]
|
|
510
|
+
* Invoked after all existing clients are destroyed.
|
|
511
|
+
*/
|
|
547
512
|
Pool.prototype.destroyAllNow = function destroyAllNow(callback) {
|
|
548
513
|
this._log('force destroying all objects', 'info');
|
|
549
|
-
|
|
514
|
+
const willDie = this._availableObjects;
|
|
550
515
|
this._availableObjects = [];
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
var obj = willDie.shift();
|
|
516
|
+
const todo = willDie.length;
|
|
517
|
+
let done = 0;
|
|
554
518
|
|
|
555
519
|
this._removeIdleScheduled = false;
|
|
556
520
|
clearTimeout(this._removeIdleTimer);
|
|
@@ -559,37 +523,30 @@ Pool.prototype.destroyAllNow = function destroyAllNow(callback) {
|
|
|
559
523
|
invoke(callback);
|
|
560
524
|
return;
|
|
561
525
|
}
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
526
|
+
|
|
527
|
+
while (willDie.length > 0) {
|
|
528
|
+
const { obj } = willDie.shift();
|
|
529
|
+
this.destroy(obj, () => {
|
|
530
|
+
done += 1;
|
|
565
531
|
if (done === todo && callback) {
|
|
566
532
|
invoke(callback);
|
|
567
|
-
return;
|
|
568
533
|
}
|
|
569
534
|
});
|
|
570
|
-
obj = willDie.shift();
|
|
571
535
|
}
|
|
572
536
|
};
|
|
573
537
|
|
|
574
538
|
/**
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
*
|
|
581
|
-
* @param {Number} priority
|
|
582
|
-
* Optional. Integer between 0 and (priorityRange - 1). Specifies the priority
|
|
583
|
-
* of the caller if there are no available resources. Lower numbers mean higher
|
|
584
|
-
* priority.
|
|
585
|
-
*/
|
|
539
|
+
* Decorates a function to use an acquired client from the pool when called.
|
|
540
|
+
*
|
|
541
|
+
* @param {Function} decorated
|
|
542
|
+
* @param {Number} [priority]
|
|
543
|
+
*/
|
|
586
544
|
Pool.prototype.pooled = function pooled(decorated, priority) {
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
self.acquire(function(err, client) {
|
|
545
|
+
return (...args) => {
|
|
546
|
+
const callerCallback = args[args.length - 1];
|
|
547
|
+
const callerHasCallback = typeof callerCallback === 'function';
|
|
548
|
+
|
|
549
|
+
this.acquire((err, client) => {
|
|
593
550
|
if (err) {
|
|
594
551
|
if (callerHasCallback) {
|
|
595
552
|
callerCallback(err);
|
|
@@ -597,15 +554,19 @@ Pool.prototype.pooled = function pooled(decorated, priority) {
|
|
|
597
554
|
return;
|
|
598
555
|
}
|
|
599
556
|
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
557
|
+
// We pass everything except the user's final callback
|
|
558
|
+
const invokeArgs = [client].concat(
|
|
559
|
+
args.slice(0, callerHasCallback ? -1 : undefined)
|
|
560
|
+
);
|
|
561
|
+
// then the final callback after we release the resource
|
|
562
|
+
invokeArgs.push((...cbArgs) => {
|
|
563
|
+
this.release(client);
|
|
603
564
|
if (callerHasCallback) {
|
|
604
|
-
callerCallback
|
|
565
|
+
callerCallback(...cbArgs);
|
|
605
566
|
}
|
|
606
567
|
});
|
|
607
568
|
|
|
608
|
-
decorated
|
|
569
|
+
decorated(...invokeArgs);
|
|
609
570
|
}, priority);
|
|
610
571
|
};
|
|
611
572
|
};
|
|
@@ -638,4 +599,4 @@ Pool.prototype.getMinPoolSize = function getMinPoolSize() {
|
|
|
638
599
|
return this._factory.min;
|
|
639
600
|
};
|
|
640
601
|
|
|
641
|
-
exports
|
|
602
|
+
module.exports = { Pool };
|