const logger = require("logops") , config = require('../../config') , { Builder, Capabilities } = require('selenium-webdriver') , pool = require('generic-pool') , { Options } = require('selenium-webdriver/chrome'); class PoolingService { constructor() { this.config = { pool: { max: 10, min: 1, testOnBorrow: true }, browser: 'chrome', browserArgs: ['--no-sandbox', '--headless', '--disable-dev-shm-usage', '--proxy-server=spiduler-tor:8118'] } this.pool = this.createPool() } createPool() { setInterval(() => this.debugPoolStatus(), 1000 * 60 * 5) return pool.createPool({ create: () => this.create(), destroy: (driver) => this.destroy(driver), validate: (driver) => this.validate(driver) }, this.config.pool); } create() { logger.info('Create new driver instance') return this.getDriver(); } destroy(driver) { logger.info('Quitting driver') return driver.quit().catch(err => { logger.debug({ message: err.message }, 'Quitting error') this.pool.release(driver) }) } validate(driver) { return driver.getSession().then(s => { logger.info('Driver session validation checked (id: %s)', s.getId()) return true }).catch(err => { this.pool.destroy(driver) logger.debug({ message: err.message }, 'Driver session expired and destroy it') return false }) } getDriver() { let opts = new Options; let capabilities = Capabilities.chrome() opts.addArguments(this.config.browserArgs) return new Builder() .usingServer('http://spiduler-chrome:4444/wd/hub') .withCapabilities(capabilities) .forBrowser(this.config.browser) .setChromeOptions(opts) .build(); } debugPoolStatus() { logger.debug({ spare: this.pool.spareResourceCapacity, size: this.pool.size, available: this.pool.available, borrowed: this.pool.borrowed, pending: this.pool.pending }, 'Pool status') } } module.exports = new PoolingService