Skip to content

Commit

Permalink
Context timeout (#48)
Browse files Browse the repository at this point in the history
* Base of timing out contexts

* Docs

---------

Co-authored-by: Alexander <[email protected]>
  • Loading branch information
MatthewZMSU and Yatskov authored Jul 22, 2024
1 parent edfb883 commit 8ef48e9
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ Here we list them all with their purpose.
* `TOKEN_2CAPTCHA = undefined` - token of [2captcha service](https://2captcha.com)
* `STEALTH_BROWSING = true` - should the service use the [stealth browsing](https://github.com/berstend/puppeteer-extra/tree/master/packages/puppeteer-extra-plugin-stealth) mode
* `MAX_CONCURRENT_CONTEXTS = undefined` - should the service limit the number of contexts
* `CONTEXT_TIMEOUT = 600000` - time (in ms) after the passage of which the context would close
* `PROMETHEUS_HOST = undefined` - host address of the metrics endpoint, if not defined then assigns to "localhost"
* `PROMETHEUS_PORT = undefined` - port of address of the metrics endpoint, if not defined then assigns to "9464"

Expand Down
3 changes: 3 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const harRouter = require('./routes/har');
const closeContextRouter = require('./routes/close_context');

const middlewares = require('./helpers/middlewares');
const timeoutContext = require('./helpers/timeout_context');
const limitContext = require('./helpers/limit_context');
const loggers = require("./helpers/loggers");

Expand All @@ -40,7 +41,9 @@ const VIEWPORT_HEIGHT = parseInt(process.env.VIEWPORT_HEIGHT) || 720;
const TOKEN_2CAPTCHA = process.env.TOKEN_2CAPTCHA;
const STEALTH_BROWSING = (process.env.STEALTH_BROWSING || "true").toLowerCase() === "true";
const MAX_CONCURRENT_CONTEXTS = process.env.MAX_CONCURRENT_CONTEXTS === "Infinity" ? Infinity : parseInt(process.env.MAX_CONCURRENT_CONTEXTS);
const CONTEXT_TIMEOUT = parseInt(process.env.CONTEXT_TIMEOUT) || 600000; // 10 minutes

timeoutContext.initTimeoutContext(CONTEXT_TIMEOUT);
limitContext.initContextCounter(MAX_CONCURRENT_CONTEXTS);
loggers.initLogger(LOG_LEVEL, LOG_FILE, LOGSTASH_HOST, LOGSTASH_PORT);

Expand Down
58 changes: 58 additions & 0 deletions helpers/timeout_context.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
const {BrowserContext} = require('puppeteer');
const loggers = require('./loggers');

/**
* ContextId -> Timeout timer' IDs
*
* @type {{string: number}}
*/
let contextTimeoutIds = {};
let contextTimeout;

/**
* Set timeout for context.
*
* @param {BrowserContext} context
*/
function setContextTimeout(context) {
const logger = loggers.getLogger();

contextTimeoutIds[context.id] = setTimeout(
async () => {
logger.warn(`Closing context ${context.id} due to timeout\n`);
await context.close();
delete contextTimeoutIds[context.id];
},
contextTimeout);
}
exports.setContextTimeout = setContextTimeout;

/**
* The function clears context's timeout timer.
*
* @param {BrowserContext} context context to be cleared
*/
function clearContextTimeout(context) {
clearTimeout(contextTimeoutIds[context.id]);
delete contextTimeoutIds[context.id];
}
exports.clearContextTimeout = clearContextTimeout;

/**
* Update timeout for context.
*
* @param {BrowserContext} context
*/
exports.updateContextTimeout = function updateContextTimeout (context) {
clearContextTimeout(context);
setContextTimeout(context);
}

/**
* Init service that timeouts contexts after CONTEXT_TIMEOUT ms.
*
* @param {number} timeout
*/
exports.initTimeoutContext = function initTimeoutContext (timeout) {
contextTimeout = timeout;
}
8 changes: 7 additions & 1 deletion helpers/utils.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const exceptions = require("./exceptions");
const { proxyRequest } = require('puppeteer-proxy');
const timeoutContext = require('./timeout_context');
const limitContext = require('./limit_context');

const PROXY_URL_KEY = 'puppeteer-service-proxy-url'
Expand Down Expand Up @@ -28,6 +29,7 @@ exports.closeContexts = async function closeContexts(browser, contextIds) {
for (const context of browser.browserContexts()) {
if (contextIds.includes(context.id)) {
limitContext.decContextCounter();
timeoutContext.clearContextTimeout(context);
closePromises.push(context.close());
}
}
Expand Down Expand Up @@ -114,8 +116,10 @@ async function newContext(browser, options = {}) {
}

try {
const context = await browser.createIncognitoBrowserContext(options);
limitContext.incContextCounter();
return await browser.createIncognitoBrowserContext(options);
timeoutContext.setContextTimeout(context);
return context
} catch (err) {
limitContext.decContextCounter();
throw err;
Expand Down Expand Up @@ -207,6 +211,8 @@ exports.performAction = async function performAction(request, action) {
delete response.pageId;
}

timeoutContext.updateContextTimeout(page.browserContext());

return response;
});
};

0 comments on commit 8ef48e9

Please sign in to comment.