futoin-asyncsteps
Version:
Mimic traditional threads in single threaded event loop
179 lines (166 loc) • 5.41 kB
JavaScript
;
/**
* @file Implementation of parallel step
* @author Andrey Galkin <andrey@futoin.org>
*
*
* Copyright 2014-2017 FutoIn Project (https://futoin.org)
* Copyright 2014-2017 Andrey Galkin <andrey@futoin.org>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
var _require = require('./common'),
checkFunc = _require.checkFunc,
checkOnError = _require.checkOnError;
/* globals AsyncSteps */
/**
* ParallelStep
* @private
* @class
* @param {AsyncSteps} [root] reference to current root object
* @param {AsyncSteps} [as] reference to current step object
*/
var ParallelStep = /*#__PURE__*/function () {
function ParallelStep(root, as) {
_classCallCheck(this, ParallelStep);
this._root = root;
this._as = as;
this._queue = [];
this._psteps = [];
this._complete_count = 0;
}
/**
* @private
* @override
*/
return _createClass(ParallelStep, [{
key: "add",
value: function add(func, onerror) {
checkFunc(this, func);
checkOnError(this, onerror);
this._queue.push([func, onerror]);
return this;
}
/**
* @private
*/
}, {
key: "_complete",
value: function _complete() {
this._complete_count += 1;
if (this._complete_count === this._psteps.length) {
this._as._root._handle_success();
this._cleanup();
}
}
/**
* @private
* @param {string} [name] Error name
* @param {string} [info] Error info
*/
}, {
key: "_error",
value: function _error(name, info) {
try {
this._as.error(name, info);
} catch (_unused) {
// ignore
}
}
/**
* @private
* @param {AsyncSteps} [as] current step interface
*/
}, {
key: "executeParallel",
value: function executeParallel(as) {
var _this = this;
var q = this._queue;
var root = this._root;
if (root !== as._root) {
var p = new ParallelStep(as._root, as);
p._queue.push.apply(p._queue, q);
p.executeParallel(as);
return;
}
this._as = as;
if (!q.length) {
this._complete();
return;
}
as._on_cancel = function () {
_this.cancel();
};
/* */
var plist = this._psteps;
var success_func = function success_func(as) {
_this._complete();
};
var error_func = function error_func(as, err) {
_this._error(err, as.state.error_info);
};
var AsyncSteps = root.constructor;
q.forEach(function (p) {
var pa = new AsyncSteps(as.state, root._async_tool);
pa._queue.push([function (as) {
as._queue = [[p[0], p[1]]];
}, error_func], [success_func, undefined]);
plist.push(pa);
});
// Should be separate from the previous loop for
// in case cancel() arrives in the middle
plist.forEach(function (p) {
// NOTE: do not use #_execute() due to lack of burst ownership handling
p.execute();
});
}
/**
* @private
*/
}, {
key: "cancel",
value: function cancel() {
this._psteps.forEach(function (p) {
p.cancel();
});
this._cleanup();
}
/**
* @private
* @override
*/
}, {
key: "isAsyncSteps",
value: function isAsyncSteps() {
return true;
}
/**
* @private
*/
}, {
key: "_cleanup",
value: function _cleanup() {
this._root = null;
this._as = null;
this._psteps = null;
}
}]);
}();
module.exports = ParallelStep;
//# sourceMappingURL=ParallelStep.js.map