@fpjs-incubator/broyster
Version:
104 lines (103 loc) • 4.65 kB
JavaScript
"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;