CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
sagemathinc

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/project/browser-websocket/symmetric_channel.ts
Views: 687
1
/*
2
* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
3
* License: MS-RSL – see LICENSE.md for details
4
*/
5
6
/*
7
Channels used for maybe nothing right now.
8
9
I thought this would be useful, but it hasn't yet turned out to be.
10
*/
11
12
import { EventEmitter } from "events";
13
14
const sync_tables = {};
15
16
function get_name(name: string): string {
17
return `symmetric_channel:${name}`;
18
}
19
20
export async function browser_symmetric_channel(
21
_: any,
22
primus: any,
23
logger: any,
24
name: string
25
): Promise<string> {
26
name = get_name(name);
27
28
// The code below is way more complicated because SymmetricChannel
29
// can be made *before* this sync function is called. If that
30
// happens, and we also have to set the channel of SymmetricChannel.
31
32
if (
33
sync_tables[name] !== undefined &&
34
sync_tables[name].channel !== undefined
35
) {
36
// fully initialized
37
return name;
38
}
39
40
const channel = primus.channel(name);
41
let local: SymmetricChannel;
42
43
if (sync_tables[name] !== undefined) {
44
local = sync_tables[name].local;
45
local.channel = channel;
46
sync_tables[name].channel = channel;
47
} else {
48
local = new SymmetricChannel(channel);
49
sync_tables[name] = {
50
local,
51
channel,
52
};
53
}
54
55
channel.on("connection", function (spark: any): void {
56
// Now handle a connection
57
logger.debug("sync", name, `conn from ${spark.address.ip} -- ${spark.id}`);
58
spark.on("end", function () {
59
logger.debug("sync", name, `closed ${spark.address.ip} -- ${spark.id}`);
60
});
61
spark.on("data", function (data) {
62
local._data_from_spark(data);
63
channel.forEach(function (spark0, id) {
64
if (id !== spark.id) {
65
spark0.write(data);
66
}
67
});
68
});
69
});
70
71
return name;
72
}
73
74
class SymmetricChannel extends EventEmitter {
75
channel: any;
76
77
constructor(channel?: any) {
78
super();
79
this.channel = channel;
80
}
81
82
// Returns true if immediate write succeeds
83
write(data: any): boolean {
84
if (this.channel !== undefined) {
85
return this.channel.write(data);
86
}
87
return false;
88
}
89
90
_data_from_spark(data: any): void {
91
this.emit("data", data);
92
}
93
}
94
95
export function symmetric_channel(name: string): SymmetricChannel {
96
name = get_name(name);
97
if (sync_tables[name] !== undefined) {
98
return sync_tables[name].local;
99
}
100
const local = new SymmetricChannel(undefined);
101
sync_tables[name] = { local };
102
return local;
103
}
104
105