@cocalc/server
Version:
CoCalc server functionality: functions used by either the hub and the next.js server
65 lines (64 loc) • 3.08 kB
JavaScript
;
/*
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