UNPKG

workflow-4-node

Version:

Workflow 4 Node is a .NET Workflow Foundation like framework for Node.js. The goal is to reach feature equivalence and beyond.

112 lines (102 loc) 3.62 kB
"use strict"; let EventEmitter = require("events").EventEmitter; let Bluebird = require("bluebird"); let async = require("../common").asyncHelpers.async; let debug = require("debug")("wf4node:WakeUp"); let util = require("util"); function WakeUp(knownInstaStore, persistence, options) { EventEmitter.call(this); this.knownInstaStore = knownInstaStore; this.persistence = persistence; this.options = options || {}; this._working = false; this._timeout = null; this._batchSize = this.options.batchSize || 10; } util.inherits(WakeUp, EventEmitter); WakeUp.prototype.start = function () { if (!this._timeout) { debug("Start."); let self = this; this._timeout = setTimeout(function () { self._step(); }, this.options.interval || 5000); } }; WakeUp.prototype.stop = function () { if (this._timeout) { debug("Stop."); clearTimeout(this._timeout); this._timeout = null; } }; WakeUp.prototype._step = async(function*() { let self = this; try { if (this._working) { debug("Skipping current step because work in progress."); return; } debug("Starting next step."); this._working = true; try { let wakeupables = yield this._getNextWakeupables(); if (wakeupables && wakeupables.length) { debug("%d selected to wake up.", wakeupables.length); let tasks = []; let count = 0; for (let wakeupable of wakeupables) { tasks.push(async(function*() { if (count >= self._batchSize) { return; } debug("Waking up workflow %s, id: %s", wakeupable.workflowName, wakeupable.instanceId); wakeupable.result = {}; let promise = new Bluebird(function (resolve, reject) { wakeupable.result.resolve = resolve; wakeupable.result.reject = reject; }); self.emit("continue", wakeupable); try { yield promise; count++; debug("Processing delay completed."); } catch (e) { debug("Processing delay error: %s", e.stack); self.emit("error", e); } })()); } let results = yield Bluebird.settle(tasks); for (let result of results) { if (result.isRejected()) { throw result.reason(); } } } else { debug("There is no instance to wake up."); } } catch (e) { this.emit("error", e); } finally { debug("Next step completed."); this._working = false; } } finally { if (this._timeout) { this._timeout = setTimeout(function () { self._step(); }, this.options.interval || 5000); } } }); WakeUp.prototype._getNextWakeupables = async(function* () { if (this.persistence) { return yield this.persistence.getNextWakeupables(this._batchSize * 1.5); } else { return this.knownInstaStore.getNextWakeupables(this._batchSize * 1.5); } }); module.exports = WakeUp;