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/project/sync/project-status.ts
Views: 687
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45import { reuseInFlight } from "@cocalc/util/reuse-in-flight";6import { close } from "@cocalc/util/misc";7import { SyncTable } from "@cocalc/sync/table";8import {9get_ProjectStatusServer,10ProjectStatusServer,11} from "../project-status";12import { ProjectStatus } from "@cocalc/comm/project-status/types";1314class ProjectStatusTable {15private table: SyncTable;16private logger: { debug: Function };17private project_id: string;18private state: "ready" | "closed" = "ready";19private readonly publish: (status: ProjectStatus) => Promise<void>;20private readonly status_server: ProjectStatusServer;2122constructor(23table: SyncTable,24logger: { debug: Function },25project_id: string,26) {27this.status_handler = this.status_handler.bind(this);28this.project_id = project_id;29this.logger = logger;30this.log("register");31this.publish = reuseInFlight(this.publish_impl.bind(this));32this.table = table;33this.table.on("closed", () => this.close());34// initializing project status server + reacting when it has something to say35this.status_server = get_ProjectStatusServer();36this.status_server.start();37this.status_server.on("status", this.status_handler);38}3940private status_handler(status): void {41this.log?.("status_server event 'status'", status.timestamp);42this.publish?.(status);43}4445private async publish_impl(status: ProjectStatus): Promise<void> {46if (this.state == "ready" && this.table.get_state() != "closed") {47const next = { project_id: this.project_id, status };48this.table.set(next, "shallow");49try {50await this.table.save();51} catch (err) {52this.log(`error saving ${err}`);53}54} else if (this.log != null) {55this.log(56`ProjectStatusTable '${57this.state58}' and table is ${this.table?.get_state()}`,59);60}61}6263public close(): void {64this.log("close");65this.status_server?.off("status", this.status_handler);66this.table?.close_no_async();67close(this);68this.state = "closed";69}7071private log(...args): void {72if (this.logger == null) return;73this.logger.debug("project_status", ...args);74}75}7677let project_status_table: ProjectStatusTable | undefined = undefined;7879export function register_project_status_table(80table: SyncTable,81logger: any,82project_id: string,83): void {84logger.debug("register_project_status_table");85if (project_status_table != null) {86logger.debug(87"register_project_status_table: cleaning up an already existing one",88);89project_status_table.close();90}91project_status_table = new ProjectStatusTable(table, logger, project_id);92}9394export function get_project_status_table(): ProjectStatusTable | undefined {95return project_status_table;96}979899