UNPKG

batch-cluster

Version:
158 lines 8.3 kB
"use strict"; var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var _Task_instances, _Task_opts, _Task_startedAt, _Task_parsing, _Task_settledAt, _Task_d, _Task_stdout, _Task_stderr, _Task_onSettle, _Task_resolve; Object.defineProperty(exports, "__esModule", { value: true }); exports.Task = void 0; const Async_1 = require("./Async"); const Deferred_1 = require("./Deferred"); let _taskId = 1; /** * Tasks embody individual jobs given to the underlying child processes. Each * instance has a promise that will be resolved or rejected based on the * result of the task. */ class Task { /** * @param {string} command is the value written to stdin to perform the given * task. * @param {Parser<T>} parser is used to parse resulting data from the * underlying process to a typed object. */ constructor(command, parser) { _Task_instances.add(this); this.command = command; this.parser = parser; this.taskId = _taskId++; _Task_opts.set(this, void 0); _Task_startedAt.set(this, void 0); _Task_parsing.set(this, false); _Task_settledAt.set(this, void 0); _Task_d.set(this, new Deferred_1.Deferred()); _Task_stdout.set(this, ""); _Task_stderr.set(this, "" /** * @param {string} command is the value written to stdin to perform the given * task. * @param {Parser<T>} parser is used to parse resulting data from the * underlying process to a typed object. */ ); // We can't use .finally here, because that creates a promise chain that, if // rejected, results in an uncaught rejection. __classPrivateFieldGet(this, _Task_d, "f").promise.then(() => __classPrivateFieldGet(this, _Task_instances, "m", _Task_onSettle).call(this), () => __classPrivateFieldGet(this, _Task_instances, "m", _Task_onSettle).call(this)); } /** * @return the resolution or rejection of this task. */ get promise() { return __classPrivateFieldGet(this, _Task_d, "f").promise; } get pending() { return __classPrivateFieldGet(this, _Task_d, "f").pending; } get state() { return __classPrivateFieldGet(this, _Task_d, "f").pending ? "pending" : __classPrivateFieldGet(this, _Task_d, "f").rejected ? "rejected" : "resolved"; } onStart(opts) { __classPrivateFieldSet(this, _Task_opts, opts, "f"); __classPrivateFieldSet(this, _Task_startedAt, Date.now(), "f"); } get runtimeMs() { var _a; return __classPrivateFieldGet(this, _Task_startedAt, "f") == null ? undefined : ((_a = __classPrivateFieldGet(this, _Task_settledAt, "f")) !== null && _a !== void 0 ? _a : Date.now()) - __classPrivateFieldGet(this, _Task_startedAt, "f"); } toString() { return (this.constructor.name + "(" + this.command.replace(/\s+/gm, " ").slice(0, 80).trim() + ")#" + this.taskId); } onStdout(buf) { var _a, _b; __classPrivateFieldSet(this, _Task_stdout, __classPrivateFieldGet(this, _Task_stdout, "f") + buf.toString(), "f"); const passRE = (_a = __classPrivateFieldGet(this, _Task_opts, "f")) === null || _a === void 0 ? void 0 : _a.passRE; if (passRE != null && passRE.exec(__classPrivateFieldGet(this, _Task_stdout, "f")) != null) { // remove the pass token from stdout: __classPrivateFieldSet(this, _Task_stdout, __classPrivateFieldGet(this, _Task_stdout, "f").replace(passRE, ""), "f"); void __classPrivateFieldGet(this, _Task_instances, "m", _Task_resolve).call(this, true); } else { const failRE = (_b = __classPrivateFieldGet(this, _Task_opts, "f")) === null || _b === void 0 ? void 0 : _b.failRE; if (failRE != null && failRE.exec(__classPrivateFieldGet(this, _Task_stdout, "f")) != null) { // remove the fail token from stdout: __classPrivateFieldSet(this, _Task_stdout, __classPrivateFieldGet(this, _Task_stdout, "f").replace(failRE, ""), "f"); void __classPrivateFieldGet(this, _Task_instances, "m", _Task_resolve).call(this, false); } } } onStderr(buf) { var _a; __classPrivateFieldSet(this, _Task_stderr, __classPrivateFieldGet(this, _Task_stderr, "f") + buf.toString(), "f"); const failRE = (_a = __classPrivateFieldGet(this, _Task_opts, "f")) === null || _a === void 0 ? void 0 : _a.failRE; if (failRE != null && failRE.exec(__classPrivateFieldGet(this, _Task_stderr, "f")) != null) { // remove the fail token from stderr: __classPrivateFieldSet(this, _Task_stderr, __classPrivateFieldGet(this, _Task_stderr, "f").replace(failRE, ""), "f"); void __classPrivateFieldGet(this, _Task_instances, "m", _Task_resolve).call(this, false); } } /** * @return true if the wrapped promise was rejected */ reject(error) { return __classPrivateFieldGet(this, _Task_d, "f").reject(error); } } exports.Task = Task; _Task_opts = new WeakMap(), _Task_startedAt = new WeakMap(), _Task_parsing = new WeakMap(), _Task_settledAt = new WeakMap(), _Task_d = new WeakMap(), _Task_stdout = new WeakMap(), _Task_stderr = new WeakMap(), _Task_instances = new WeakSet(), _Task_onSettle = function _Task_onSettle() { var _a; __classPrivateFieldSet(this, _Task_settledAt, (_a = __classPrivateFieldGet(this, _Task_settledAt, "f")) !== null && _a !== void 0 ? _a : Date.now(), "f"); }, _Task_resolve = async function _Task_resolve(passed) { var _a, _b, _c; // fail always wins. passed = !__classPrivateFieldGet(this, _Task_d, "f").rejected && passed; // wait for stderr and stdout to flush: const flushMs = (_b = (_a = __classPrivateFieldGet(this, _Task_opts, "f")) === null || _a === void 0 ? void 0 : _a.streamFlushMillis) !== null && _b !== void 0 ? _b : 0; if (flushMs > 0) { await (0, Async_1.delay)(flushMs); } // we're expecting this method may be called concurrently (if there are both // pass and fail tokens found in stderr and stdout), but we only want to run // this once, so if (!this.pending || __classPrivateFieldGet(this, _Task_parsing, "f")) return; // this.#opts // ?.logger() // .trace("Task.#resolve()", { command: this.command, state: this.state }) // Prevent concurrent parsing: __classPrivateFieldSet(this, _Task_parsing, true, "f"); try { const parseResult = await this.parser(__classPrivateFieldGet(this, _Task_stdout, "f"), __classPrivateFieldGet(this, _Task_stderr, "f"), passed); if (__classPrivateFieldGet(this, _Task_d, "f").resolve(parseResult)) { // success } else { (_c = __classPrivateFieldGet(this, _Task_opts, "f")) === null || _c === void 0 ? void 0 : _c.observer.emit("internalError", new Error(this.toString() + " ._resolved() more than once")); } } catch (error) { this.reject(error instanceof Error ? error : new Error(String(error))); } }; //# sourceMappingURL=Task.js.map