Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
async _maybeLoadSessionPool() {
const loadedSessionPool = await this.keyValueStore.getValue(this.persistStateKey);
if (!loadedSessionPool) return;
// Invalidate old sessions and load active sessions only
log.debug('SessionPool: Recreating state from KeyValueStore',
{
persistStateKeyValueStoreId: this.persistStateKeyValueStoreId,
persistStateKey: this.persistStateKey,
});
for (const sessionObject of loadedSessionPool.sessions) {
sessionObject.sessionPool = this;
sessionObject.createdAt = new Date(sessionObject.createdAt);
sessionObject.expiresAt = new Date(sessionObject.expiresAt);
const recreatedSession = new Session(sessionObject);
if (recreatedSession.isUsable()) {
this._addSession(recreatedSession);
}
}
log.debug(`SessionPool: ${this.usableSessionsCount} active sessions loaded from KeyValueStore`);
// Update logData even if not scaling down
if (logData) {
Object.assign(logData, {
concurrency: this.concurrency,
isMemoryOverloaded,
isCpuOverloaded,
});
}
if (this.intervalCounter % SCALE_DOWN_INTERVAL !== 0
|| this.concurrency <= this.minConcurrency
|| (!isCpuOverloaded && !isMemoryOverloaded)) return false;
this.concurrency--;
log.debug('AutoscaledPool: scaling down', {
oldConcurrency: this.concurrency + 1,
newConcurrency: this.concurrency,
isMemoryOverloaded,
isCpuOverloaded,
});
return true;
}
_.mapObject(this.retiredInstances, async (instance) => {
// Kill instances that are more than this.killInstanceAfterMillis from last opened page
if (Date.now() - instance.lastPageOpenedAt > this.killInstanceAfterMillis) {
log.debug('PuppeteerPool: killing retired browser after period of inactivity', { id: instance.id, killInstanceAfterMillis: this.killInstanceAfterMillis }); // eslint-disable-line max-len
this._killInstance(instance);
return;
}
try {
const browser = await instance.browserPromise;
const pages = await browser.pages();
// NOTE: we are killing instance when the number of pages is less or equal to 1 because there is always about:blank page.
if (pages.length <= 1) {
log.debug('PuppeteerPool: Killing retired browser because it has no open tabs', { id: instance.id });
this._killInstance(instance);
}
} catch (err) {
log.exception(err, 'PuppeteerPool: Browser.pages() failed', { id: instance.id });
this._killInstance(instance);
}
});
}
socket.on('getLastSnapshot', () => {
if (this.lastSnapshot) {
log.debug('Sending live view snapshot', { createdAt: this.lastSnapshot.createdAt, pageUrl: this.lastSnapshot.pageUrl });
this.socketio.emit('snapshot', this.lastSnapshot);
}
});
}
async recyclePage(page) {
const snapshotPromise = this.liveViewSnapshotsInProgress.get(page);
if (snapshotPromise) await snapshotPromise;
if (this.reusePages) {
page.removeAllListeners();
this.idlePages.push(page);
} else {
try {
await addTimeoutToPromise(
page.close(),
this.puppeteerOperationTimeoutMillis,
'PuppeteerPool: page.close() timed out.',
);
} catch (err) {
log.debug('PuppeteerPool: page.close() failed.', { reason: err && err.message });
}
}
}
async retire(browser) {
const instance = await this._findInstanceByBrowser(browser);
if (instance) return this._retireInstance(instance);
log.debug('PuppeteerPool: Browser is retired already');
}
{
persistStateKeyValueStoreId: this.persistStateKeyValueStoreId,
persistStateKey: this.persistStateKey,
});
for (const sessionObject of loadedSessionPool.sessions) {
sessionObject.sessionPool = this;
sessionObject.createdAt = new Date(sessionObject.createdAt);
sessionObject.expiresAt = new Date(sessionObject.expiresAt);
const recreatedSession = new Session(sessionObject);
if (recreatedSession.isUsable()) {
this._addSession(recreatedSession);
}
}
log.debug(`SessionPool: ${this.usableSessionsCount} active sessions loaded from KeyValueStore`);
}
}
_scaleUp(systemStatus) {
const step = Math.ceil(this._desiredConcurrency * this.scaleUpStepRatio);
this._desiredConcurrency = Math.min(this._maxConcurrency, this._desiredConcurrency + step);
log.debug('AutoscaledPool: scaling up', {
oldConcurrency: this._desiredConcurrency - step,
newConcurrency: this._desiredConcurrency,
systemStatus,
});
}
.catch(err => log.debug('Live View failed to be served.', { message: err.message }));
this.liveViewSnapshotsInProgress.set(page, snapshotPromise);