UNPKG

@splitsoftware/splitio-commons

Version:
85 lines (84 loc) 3.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.syncTaskFactory = void 0; var constants_1 = require("../logger/constants"); /** * Creates an object that handles the periodic execution of a given task via "start" and "stop" methods. * The task can be also executed by calling the "execute" method. Multiple calls run sequentially to avoid race conditions (e.g., submitters executed on SDK destroy or full queue, while periodic execution is pending). * * @param log - Logger instance. * @param task - Task to execute that returns a promise that NEVER REJECTS. Otherwise, periodic execution can result in Unhandled Promise Rejections. * @param period - Period in milliseconds to execute the task. * @param taskName - Optional task name for logging. * @returns A sync task that wraps the given task. */ function syncTaskFactory(log, task, period, taskName) { if (taskName === void 0) { taskName = 'task'; } // Flag that indicates if the task is executing var executing = 0; // Promise chain to resolve tasks sequentially var promiseChain; // flag that indicates if the task periodic execution has been started/stopped. var running = false; // Auxiliar counter used to avoid race condition when calling `start` & `stop` intermittently var runningId = 0; // Params passed to `task` when called periodically var runningArgs; // Id of the periodic call timeout var timeoutID; function execute() { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } executing++; log.debug(constants_1.SYNC_TASK_EXECUTE, [taskName]); // Update `promiseChain` with last promise, to run tasks serially promiseChain = (promiseChain ? promiseChain.then(function () { return task.apply(void 0, args); }) : task.apply(void 0, args)) .then(function (result) { executing--; return result; }); return promiseChain; } function periodicExecute(currentRunningId) { return execute.apply(void 0, runningArgs).then(function (result) { // Call `setTimeout` if periodic execution was started and `currentRunningId === runningId` // to avoid a race condition when calling `start`, `stop` and `start` again if (running && currentRunningId === runningId) timeoutID = setTimeout(periodicExecute, period, currentRunningId); return result; }); } return { execute: execute, isExecuting: function () { return executing > 0; }, start: function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } if (!running) { running = true; runningId++; runningArgs = args; log.debug(constants_1.SYNC_TASK_START, [taskName, period]); return periodicExecute(runningId); } }, stop: function () { if (running) { running = false; log.debug(constants_1.SYNC_TASK_STOP, [taskName]); clearTimeout(timeoutID); timeoutID = undefined; } }, isRunning: function () { return running; } }; } exports.syncTaskFactory = syncTaskFactory;