wallet-core/node_modules/async/internal/queue.js

184 lines
5.2 KiB
JavaScript
Raw Normal View History

2016-10-10 03:43:44 +02:00
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = queue;
var _arrayEach = require('lodash/_arrayEach');
var _arrayEach2 = _interopRequireDefault(_arrayEach);
var _isArray = require('lodash/isArray');
var _isArray2 = _interopRequireDefault(_isArray);
var _noop = require('lodash/noop');
var _noop2 = _interopRequireDefault(_noop);
var _rest = require('lodash/rest');
var _rest2 = _interopRequireDefault(_rest);
var _onlyOnce = require('./onlyOnce');
var _onlyOnce2 = _interopRequireDefault(_onlyOnce);
var _setImmediate = require('./setImmediate');
var _setImmediate2 = _interopRequireDefault(_setImmediate);
var _DoublyLinkedList = require('./DoublyLinkedList');
var _DoublyLinkedList2 = _interopRequireDefault(_DoublyLinkedList);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function queue(worker, concurrency, payload) {
if (concurrency == null) {
concurrency = 1;
} else if (concurrency === 0) {
throw new Error('Concurrency must not be zero');
}
function _insert(data, insertAtFront, callback) {
if (callback != null && typeof callback !== 'function') {
throw new Error('task callback must be a function');
}
q.started = true;
if (!(0, _isArray2.default)(data)) {
data = [data];
}
if (data.length === 0 && q.idle()) {
// call drain immediately if there are no tasks
return (0, _setImmediate2.default)(function () {
q.drain();
});
}
(0, _arrayEach2.default)(data, function (task) {
var item = {
data: task,
callback: callback || _noop2.default
};
if (insertAtFront) {
q._tasks.unshift(item);
} else {
q._tasks.push(item);
}
});
(0, _setImmediate2.default)(q.process);
}
function _next(tasks) {
return (0, _rest2.default)(function (args) {
workers -= 1;
(0, _arrayEach2.default)(tasks, function (task) {
(0, _arrayEach2.default)(workersList, function (worker, index) {
if (worker === task) {
workersList.splice(index, 1);
return false;
}
});
task.callback.apply(task, args);
if (args[0] != null) {
q.error(args[0], task.data);
}
});
if (workers <= q.concurrency - q.buffer) {
q.unsaturated();
}
if (q.idle()) {
q.drain();
}
q.process();
});
}
var workers = 0;
var workersList = [];
var q = {
_tasks: new _DoublyLinkedList2.default(),
concurrency: concurrency,
payload: payload,
saturated: _noop2.default,
unsaturated: _noop2.default,
buffer: concurrency / 4,
empty: _noop2.default,
drain: _noop2.default,
error: _noop2.default,
started: false,
paused: false,
push: function (data, callback) {
_insert(data, false, callback);
},
kill: function () {
q.drain = _noop2.default;
q._tasks.empty();
},
unshift: function (data, callback) {
_insert(data, true, callback);
},
process: function () {
while (!q.paused && workers < q.concurrency && q._tasks.length) {
var tasks = [],
data = [];
var l = q._tasks.length;
if (q.payload) l = Math.min(l, q.payload);
for (var i = 0; i < l; i++) {
var node = q._tasks.shift();
tasks.push(node);
data.push(node.data);
}
if (q._tasks.length === 0) {
q.empty();
}
workers += 1;
workersList.push(tasks[0]);
if (workers === q.concurrency) {
q.saturated();
}
var cb = (0, _onlyOnce2.default)(_next(tasks));
worker(data, cb);
}
},
length: function () {
return q._tasks.length;
},
running: function () {
return workers;
},
workersList: function () {
return workersList;
},
idle: function () {
return q._tasks.length + workers === 0;
},
pause: function () {
q.paused = true;
},
resume: function () {
if (q.paused === false) {
return;
}
q.paused = false;
var resumeCount = Math.min(q.concurrency, q._tasks.length);
// Need to call q.process once per concurrent
// worker to preserve full concurrency after pause
for (var w = 1; w <= resumeCount; w++) {
(0, _setImmediate2.default)(q.process);
}
}
};
return q;
}
module.exports = exports['default'];