UNPKG

@cocalc/server

Version:

CoCalc server functionality: functions used by either the hub and the next.js server

65 lines (64 loc) 3.08 kB
"use strict"; /* The default export is an init function that watches for projects that are idle too long and stops them. If you set the environment variable COCALC_NO_IDLE_TIMEOUT, then this is not used. It would be better to use the database and a server setting for this, but an env variable is very fast to implement. */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const logger_1 = __importDefault(require("@cocalc/backend/logger")); const async_utils_1 = require("@cocalc/util/async-utils"); const database_1 = require("@cocalc/database"); const upgrade_spec_1 = require("@cocalc/util/upgrade-spec"); const logger = (0, logger_1.default)("stop-idle-projects"); async function stopIdleProjects(stopProject) { logger.info("stopping all idle projects"); logger.debug("query database for all running projects"); const runningProjects = (await (0, async_utils_1.callback2)((0, database_1.db)()._query, { // ::float necessary for Postgres 14, see @cocalc/database/pool/util.ts timeInSeconds for more info query: `SELECT project_id, (EXTRACT(EPOCH FROM NOW() - last_edited))::FLOAT as idle_time, settings, run_quota FROM projects WHERE state ->> 'state' = 'running'`, })).rows; logger.debug("got ", runningProjects); for (const project of runningProjects) { const { project_id, idle_time, settings, run_quota } = project; // take the run_quota or the admin setting into account (if nothing, then the default) // and in any case, at lesat 10 mintues const mintime = Math.max(10 * 60, run_quota?.idle_timeout ?? settings?.mintime ?? upgrade_spec_1.DEFAULT_QUOTAS.mintime); const always_running = settings?.always_running ?? false; if (!always_running && idle_time > mintime) { // stopProject is async, but we don't await it (and it doesn't raise), // since we want to immediately stop all of them, rather than waiting // and stopping based on outdated information. stopProject(project_id); } } } function init(getProject) { if (process.env.COCALC_NO_IDLE_TIMEOUT) { logger.info("NOT initializing idle project stop loop since COCALC_NO_IDLE_TIMEOUT to set"); return; } logger.info("initializing idle project stop loop (set environment variable COCALC_NO_IDLE_TIMEOUT to disable)"); const stopProject = async (project_id) => { logger.info(`stopping ${project_id} due to idle timeout`); try { (await getProject(project_id)).stop(); logger.debug(`stopped ${project_id} successfully`); } catch (err) { logger.error(`error stopping ${project_id} -- ${err}`); } }; setInterval(() => { stopIdleProjects(stopProject); }, 60000); stopIdleProjects(stopProject); } exports.default = init; //# sourceMappingURL=stop-idle-projects.js.map