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/jupyter/pool/pool-params.ts
Views: 687
1
/*
2
* This file is part of CoCalc: Copyright © 2023 Sagemath, Inc.
3
* License: MS-RSL – see LICENSE.md for details
4
*/
5
6
// Parameters for the Jupyter Pool
7
// They're loaded right after custom env variables are set, such that not only admins of the platform,
8
// but also users on their own can tune them.
9
10
import { join } from "node:path";
11
import { homedir } from "node:os";
12
import getLogger from "@cocalc/backend/logger";
13
14
const logger = getLogger("jupyter:pool-params");
15
16
// read env vars with that prefix
17
const PREFIX = "COCALC_JUPYTER_POOL";
18
// avoid craziness:
19
const MAX_POOL_SIZE = 10;
20
21
// the defaults
22
const CONFIG_FILENAME = `cocalc-jupyter-pool${
23
process.env.COMPUTE_SERVER_ID ?? ""
24
}`;
25
const CONFIG_DIR = join(homedir(), ".config");
26
const CONFIG = join(CONFIG_DIR, CONFIG_FILENAME);
27
// size of pool, set to 0 to disable it.
28
function getPoolSize(): number {
29
try {
30
const size = parseInt(process.env.COCALC_JUPYTER_POOL_SIZE ?? "1");
31
if (!isFinite(size)) {
32
logger.debug(
33
"getPoolSize ",
34
process.env.COCALC_JUPYTER_POOL_SIZE,
35
" not finite",
36
);
37
// disable
38
return 0;
39
}
40
if (size < 0) {
41
logger.debug(
42
"getPoolSize ",
43
process.env.COCALC_JUPYTER_POOL_SIZE,
44
" negative -- setting to 0",
45
);
46
return 0;
47
}
48
if (size > MAX_POOL_SIZE) {
49
return MAX_POOL_SIZE;
50
}
51
return size;
52
} catch (err) {
53
logger.debug("getPoolSize -- error -- disabling pool", err);
54
return 0;
55
}
56
return 0;
57
}
58
const SIZE = getPoolSize();
59
const TIMEOUT_S = 3600; // after that time, clean up old kernels in the pool
60
const LAUNCH_DELAY_MS = 7500; // additional delay before spawning an additional kernel
61
62
const PARAMS = {
63
SIZE,
64
TIMEOUT_S,
65
LAUNCH_DELAY_MS,
66
CONFIG_FILENAME,
67
CONFIG_DIR,
68
CONFIG,
69
};
70
71
export function init() {
72
// at this point, project-setup::set_extra_env has already been called.
73
// hence process.env contains global env vars set in init.sh and user specified env vars
74
const env = process.env;
75
for (const key in PARAMS) {
76
// we derive the full path, see end of this function
77
if (key === "CONFIG") continue;
78
const varName = `${PREFIX}_${key}`;
79
if (varName in env) {
80
const val = env[varName];
81
if (val === "") continue; // ignore empty values
82
// if val can be converted to a number, use the integer value
83
const num = Number(val);
84
if (!Number.isNaN(num)) {
85
logger.debug(`setting ${key} to ${num} (converted from '${val}')`);
86
PARAMS[key] = num;
87
} else {
88
logger.debug(`setting ${key} to '${val}'`);
89
PARAMS[key] = val;
90
}
91
}
92
}
93
PARAMS.CONFIG = join(PARAMS.CONFIG_DIR, PARAMS.CONFIG_FILENAME);
94
logger.debug("jupyter kernel pool parameters: ", PARAMS);
95
}
96
97
export function getSize(): number {
98
return PARAMS.SIZE;
99
}
100
101
export function getTimeoutS(): number {
102
return PARAMS.TIMEOUT_S;
103
}
104
105
export function getLaunchDelayMS(): number {
106
return PARAMS.LAUNCH_DELAY_MS;
107
}
108
109
export function getConfig(): string {
110
return PARAMS.CONFIG;
111
}
112
113
export function getConfigDir(): string {
114
return PARAMS.CONFIG_DIR;
115
}
116
117