UNPKG

@fpjs-incubator/broyster

Version:
104 lines (103 loc) 4.65 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.makeBrowserStackSessionsManager = exports.BrowserStackSessionsManager = void 0; const tslib_1 = require("tslib"); const AsyncLock = require("async-lock"); const queue_state_1 = require("./queue_state"); const queue_error_1 = require("./queue_error"); const browserstack_helpers_1 = require("./browserstack_helpers"); class BrowserStackSessionsManager { constructor(config, _credentials) { var _a, _b, _c; this._credentials = _credentials; this._lock = new AsyncLock(); this._state = queue_state_1.QueueState.Pending; this._queueTimeout = (_b = (_a = config.browserStack) === null || _a === void 0 ? void 0 : _a.queueTimeout) !== null && _b !== void 0 ? _b : 300000; this._timeout = Date.now() + this._queueTimeout; this._requiredSlots = (_c = config.concurrency) !== null && _c !== void 0 ? _c : 1; } canNewSessionBeLaunched(log) { return tslib_1.__awaiter(this, void 0, void 0, function* () { return yield this.checkIfCanLaunchSessions(1, log); }); } ensureQueue(launcher, log) { return tslib_1.__awaiter(this, void 0, void 0, function* () { const isAvailable = yield this.getQueue(launcher, log); if (isAvailable) { yield this.getNewLauncher(log); } }); } getNewLauncher(log) { return tslib_1.__awaiter(this, void 0, void 0, function* () { const timeout = Date.now() + this._queueTimeout; while (!(yield this.canNewSessionBeLaunched(log))) { if (Date.now() > timeout) { log.debug('launcher timeout exceeded'); throw new queue_error_1.QueueError('Queue for new launcher timed out. Browser will not launch'); } log.debug('waiting for launcher'); yield new Promise((r) => setTimeout(r, 1000)); } }); } getQueue(launcher, log) { return tslib_1.__awaiter(this, void 0, void 0, function* () { if (this._state === queue_state_1.QueueState.Pending) { yield this._lock.acquire('queueLock', () => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield this.waitForQueue(log); })); } if (this._state === queue_state_1.QueueState.Timedout) { launcher.kill(); log.info('queue timed out'); throw new queue_error_1.QueueError('Queue not available within timeout. Browser will not launch: ' + launcher.id); } return true; }); } waitForQueue(log) { return tslib_1.__awaiter(this, void 0, void 0, function* () { log.debug('queue state is ' + this._state); if (this._state !== queue_state_1.QueueState.Pending) { log.debug('returning'); return; } log.info('waiting for BrowserStack to have free slots: ' + this._requiredSlots); log.info('expected timeout to be at ' + new Date(this._timeout).toISOString()); while (!(yield this.checkIfNewSessionCanBeQueued(log))) { if (Date.now() > this._timeout) { log.info('queue timeout exceeded, failing'); this.setTimedout(); return; } log.debug('waiting for queue'); yield new Promise((r) => setTimeout(r, 1000)); } log.info('enough slots free'); this.setFree(); }); } setFree() { this._state = queue_state_1.QueueState.Available; this._timeout = Date.now() + 60000; } setTimedout() { this._state = queue_state_1.QueueState.Timedout; this._timeout = Date.now() - 60000; } checkIfNewSessionCanBeQueued(log) { return this.checkIfCanLaunchSessions(this._requiredSlots, log); } checkIfCanLaunchSessions(slots, log) { return this._lock.acquire('sessionsLock', () => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield (0, browserstack_helpers_1.canNewBrowserBeQueued)(this._credentials, slots, log); })); } } exports.BrowserStackSessionsManager = BrowserStackSessionsManager; function makeBrowserStackSessionsManager(config, browserStackCredentials) { return new BrowserStackSessionsManager(config, browserStackCredentials); } exports.makeBrowserStackSessionsManager = makeBrowserStackSessionsManager;