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/jupyter/upstream-jupyter.ts
Views: 687
1
/*
2
Start official upstream Jupyter(Lab) server if necessary, then send a message
3
to the hub with the port the server is serving on.
4
5
This is used by the proxy server to route a certain URL to jupyter(lab).
6
7
- socket -- TCP connection between project and hub
8
- mesg -- the message from the hub requesting the jupyter port.
9
*/
10
11
import { promisify } from "util";
12
import { exec as fs_exec } from "child_process";
13
import { getLogger } from "@cocalc/project/logger";
14
15
const exec = promisify(fs_exec);
16
const winston = getLogger("upstream-jupyter");
17
18
export default async function getPort(lab: boolean = false): Promise<number> {
19
let s: { port?: number; status?: string } = await status(lab);
20
winston.debug(`jupyter_port, lab=${lab}, status = ${JSON.stringify(s)}`);
21
if (!s.port || s.status != "running") {
22
winston.debug("getPort: not running so start");
23
s = await start(lab);
24
}
25
if (!s.port || s.status != "running") {
26
throw Error(`unable to start jupyter ${lab ? "lab" : "classic"}`);
27
}
28
29
winston.debug(
30
`getPort: started jupyter ${lab ? "lab" : "classic"} at port ${s.port}`
31
);
32
return s.port;
33
}
34
35
async function cmd(arg: string, lab: boolean) {
36
const command = `cc-jupyter${lab ? "lab" : ""} ${arg}`;
37
winston.debug(command);
38
return await exec(command);
39
}
40
41
async function start(
42
lab: boolean
43
): Promise<{ base: string; pid: number; port: number }> {
44
const { stdout } = await cmd("start", lab);
45
return JSON.parse(stdout);
46
}
47
48
async function status(
49
lab: boolean
50
): Promise<{ status: "stopped" | "running"; port?: number }> {
51
try {
52
const { stdout } = await cmd("status", lab);
53
return JSON.parse(stdout);
54
} catch (err) {
55
return { status: "stopped" };
56
}
57
}
58
59