UNPKG

@cocalc/server

Version:

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

86 lines 3.67 kB
"use strict"; /* Handle all mentions that haven't yet been handled. */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const pool_1 = __importDefault(require("@cocalc/database/pool")); const awaiting_1 = require("awaiting"); const logger_1 = require("@cocalc/backend/logger"); const notify_1 = __importDefault(require("./notify")); const logger = (0, logger_1.getLogger)("mentions - handle"); // TODO: should be in the database server settings; also should be // user configurable, and this is just a default const minEmailInterval = "6 hours"; const maxPerInterval = 50; // up to 50 emails for a given chatroom every 6 hours. // We check for new notifications this frequently. const polIntervalSeconds = 15; // Handle all notification, then wait for the given time, then again // handle all unhandled notifications. async function init() { while (true) { try { await handleAllMentions(); } catch (err) { logger.warn(`WARNING -- error handling mentions -- ${err}`); } await (0, awaiting_1.delay)(polIntervalSeconds * 1000); } } exports.default = init; async function handleAllMentions() { const pool = (0, pool_1.default)(); const { rows } = await pool.query("SELECT time, project_id, path, source, target, description, fragment_id FROM mentions WHERE action IS null"); for (const row of rows) { const { time, project_id, path, source, target, description, fragment_id } = row; try { await handleMention({ project_id, path, time, target, fragment_id }, source, description ?? ""); } catch (err) { logger.warn(`WARNING -- error handling mention (will try later) -- ${err}`); } } } async function handleMention(key, source, description) { // Check that source and target are both currently // collaborators on the project. const action = await determineAction(key); try { switch (action) { case "ignore": // already recently notified about this chatroom. await setAction(key, action); return; case "notify": let whatDid = await (0, notify_1.default)(key, source, description); // record what we did. await setAction(key, whatDid); return; default: throw Error(`BUG: unknown action "${action}"`); } } catch (err) { await setError(key, action, `${err}`); } } async function determineAction(key) { const pool = (0, pool_1.default)(); const { rows } = await pool.query(`SELECT COUNT(*)::INT FROM mentions WHERE project_id=$1 AND path=$2 AND target=$3 AND action = 'email' AND time >= NOW() - INTERVAL '${parseInt(minEmailInterval)}'`, [key.project_id, key.path, key.target]); const count = rows[0]?.count ?? 0; if (count >= maxPerInterval) { return "ignore"; } return "notify"; } async function setAction(key, action) { const pool = (0, pool_1.default)(); await pool.query("UPDATE mentions SET action=$1 WHERE project_id=$2 AND path=$3 AND time=$4 AND target=$5", [action, key.project_id, key.path, key.time, key.target]); } async function setError(key, action, error) { const pool = (0, pool_1.default)(); await pool.query("UPDATE mentions SET action=$1, error=$2 WHERE project_id=$3 AND path=$4 AND time=$5 AND target=$6", [action, error, key.project_id, key.path, key.time, key.target]); } //# sourceMappingURL=handle.js.map