UNPKG

@cocalc/project

Version:
104 lines (86 loc) 2.45 kB
/* * This file is part of CoCalc: Copyright © 2020 Sagemath, Inc. * License: AGPLv3 s.t. "Commons Clause" – see LICENSE.md for details */ /* Channels used for maybe nothing right now. I thought this would be useful, but it hasn't yet turned out to be. */ import { EventEmitter } from "events"; const sync_tables = {}; function get_name(name: string): string { return `symmetric_channel:${name}`; } export async function browser_symmetric_channel( _: any, primus: any, logger: any, name: string ): Promise<string> { name = get_name(name); // The code below is way more complicated because SymmetricChannel // can be made *before* this sync function is called. If that // happens, and we also have to set the channel of SymmetricChannel. if ( sync_tables[name] !== undefined && sync_tables[name].channel !== undefined ) { // fully initialized return name; } const channel = primus.channel(name); let local: SymmetricChannel; if (sync_tables[name] !== undefined) { local = sync_tables[name].local; local.channel = channel; sync_tables[name].channel = channel; } else { local = new SymmetricChannel(channel); sync_tables[name] = { local, channel, }; } channel.on("connection", function (spark: any): void { // Now handle a connection logger.debug("sync", name, `conn from ${spark.address.ip} -- ${spark.id}`); spark.on("end", function () { logger.debug("sync", name, `closed ${spark.address.ip} -- ${spark.id}`); }); spark.on("data", function (data) { local._data_from_spark(data); channel.forEach(function (spark0, id) { if (id !== spark.id) { spark0.write(data); } }); }); }); return name; } class SymmetricChannel extends EventEmitter { channel: any; constructor(channel?: any) { super(); this.channel = channel; } // Returns true if immediate write succeeds write(data: any): boolean { if (this.channel !== undefined) { return this.channel.write(data); } return false; } _data_from_spark(data: any): void { this.emit("data", data); } } export function symmetric_channel(name: string): SymmetricChannel { name = get_name(name); if (sync_tables[name] !== undefined) { return sync_tables[name].local; } const local = new SymmetricChannel(undefined); sync_tables[name] = { local }; return local; }