Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/src/packages/database/postgres/always-running.ts
Views: 687
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45import { delay } from "awaiting";6import { PostgreSQL } from "./types";78// Return an array of project_id's of projects that have the always_running run_quota set,9// but are not in the running or starting state.10// We only check for stable states, i.e. there is no state transition going on right now.11// Ref: @cocalc/util/compute-states.js12// Performance:13// - only an `x IN <array>` clause uses the index, not a `NOT IN`.14// - settings ->> 'always_running' is indexed as TEXT, hence we match on the string "1" (no INT conversations)15export async function projects_that_need_to_be_started(16database: PostgreSQL,17limit = 10,18): Promise<string[]> {19const result = await database.async_query({20query: `SELECT project_id FROM projects21WHERE deleted IS NOT TRUE22AND (run_quota ->> 'always_running' = 'true' OR (settings ->> 'always_running')::TEXT = '1')23AND (state ->> 'state' IN ('archived', 'closed', 'opened') OR state IS NULL)24LIMIT ${limit}`,25});26const projects: string[] = [];27for (const row of result.rows) {28projects.push(row.project_id);29}30return projects;31// TODO: as mentioned above, need to also handle always_running coming from applied licenses,32// which will be way more complicated.33}3435export async function init_start_always_running_projects(36database: PostgreSQL,37interval_s: number = 15,38): Promise<void> {39while (true) {40try {41for (const project_id of await projects_that_need_to_be_started(42database,43)) {44const projectControl = (database as any).projectControl;45if (projectControl == null) continue; // not initialized (?)46const project = projectControl(project_id);47project.start(); // we fire this off, but do not wait on it48}49} catch (err) {50console.warn("init_start_always_running_projects", err);51}52await delay(interval_s * 1000);53}54}555657