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/retention/index.ts
Views: 687
import getPool from "../../pool";1import getLogger from "@cocalc/backend/logger";2import type { RetentionModel } from "@cocalc/util/db-schema";3import activeUsers from "./active-users";4import retainedUsers from "./retained-users";56const log = getLogger("database:retention");78type Period =9| { seconds: number }10| { hours: number }11| { days: number }12| { months: number }13| { years: number };1415interface Options {16start: Date;17stop: Date;18model: RetentionModel;19period: Period;20}2122export async function updateRetentionData({23start,24stop,25model,26period,27}: Options) {28if (start == null || stop == null || model == null || period == null) {29log.debug("some input is null so nothing to do");30// nothing to do31return;32}33if (typeof start == "object" && start["="]) {34start = start["="];35}36if (typeof stop == "object" && stop["="]) {37stop = stop["="];38}39if (typeof model == "object" && model["="]) {40model = model["="];41}42if (typeof period == "object" && period["="]) {43period = period["="];44}45const pool = getPool();46const current = await pool.query(47"SELECT last_start_time, NOW() - $4::interval - $4::interval AS required_last_start_time FROM crm_retention WHERE start=$1 AND stop=$2 AND model=$3 AND period=$4",48[start, stop, model, period]49);50log.debug(current);5152if (53current.rows.length > 0 &&54current.rows[0].last_start_time >= current.rows[0].required_last_start_time55) {56log.debug("have the data, so nothing to do");57// nothing to do.58return;59}60log.debug("need to compute data", JSON.stringify(current.rows?.[0]));6162// We do a check to make sure the interval is not too short to avoid a massive63// computation. This could easily happen, e.g., when playing around in the crm.64const { rows } = await pool.query(65"SELECT extract(epoch FROM $1::interval) AS seconds",66[period]67);68if (rows[0].seconds < 3600) {69throw Error("period must be at least one hour long");70// TODO: stronger constraint involving start?71}72const last_start_time = current.rows[0]?.last_start_time;7374const [table, isActiveUsers] = model.split(":");7576if (isActiveUsers) {77await activeUsers({78table,79model,80last_start_time,81pool,82start,83stop,84period,85});86} else {87await retainedUsers({88table,89model,90last_start_time,91pool,92start,93stop,94period,95});96}97}9899100