Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/project/conat/connection.ts
1447 views
1
/*
2
Create a connection to a conat server authenticated as a project or compute
3
server, via an api key or the project secret token.
4
*/
5
6
import { apiKey, conatServer } from "@cocalc/backend/data";
7
import { secretToken } from "@cocalc/project/data";
8
import { connect, type Client } from "@cocalc/conat/core/client";
9
import {
10
API_COOKIE_NAME,
11
PROJECT_SECRET_COOKIE_NAME,
12
PROJECT_ID_COOKIE_NAME,
13
} from "@cocalc/backend/auth/cookie-names";
14
import { inboxPrefix } from "@cocalc/conat/names";
15
import { setConatClient } from "@cocalc/conat/client";
16
import { compute_server_id, project_id } from "@cocalc/project/data";
17
import { version as ourVersion } from "@cocalc/util/smc-version";
18
import { getLogger } from "@cocalc/project/logger";
19
import { initHubApi } from "@cocalc/conat/hub/api";
20
import { delay } from "awaiting";
21
22
const logger = getLogger("conat:connection");
23
24
const VERSION_CHECK_INTERVAL = 2 * 60000;
25
26
let cache: Client | null = null;
27
export function connectToConat(options?): Client {
28
if (cache != null) {
29
return cache;
30
}
31
let Cookie;
32
if (apiKey) {
33
Cookie = `${API_COOKIE_NAME}=${apiKey}`;
34
} else {
35
Cookie = `${PROJECT_SECRET_COOKIE_NAME}=${secretToken}; ${PROJECT_ID_COOKIE_NAME}=${project_id}`;
36
}
37
cache = connect({
38
address: conatServer,
39
inboxPrefix: inboxPrefix({ project_id }),
40
extraHeaders: { Cookie },
41
...options,
42
});
43
44
versionCheckLoop(cache);
45
46
return cache!;
47
}
48
49
export function init() {
50
setConatClient({
51
conat: connectToConat,
52
project_id,
53
compute_server_id,
54
getLogger,
55
});
56
}
57
init();
58
59
async function callHub({
60
client,
61
service = "api",
62
name,
63
args = [],
64
timeout,
65
}: {
66
client: Client;
67
service?: string;
68
name: string;
69
args: any[];
70
timeout?: number;
71
}) {
72
const subject = `hub.project.${project_id}.${service}`;
73
try {
74
const data = { name, args };
75
const resp = await client.request(subject, data, { timeout });
76
return resp.data;
77
} catch (err) {
78
err.message = `${err.message} - callHub: subject='${subject}', name='${name}', `;
79
throw err;
80
}
81
}
82
83
async function versionCheckLoop(client) {
84
const hub = initHubApi((opts) => callHub({ ...opts, client }));
85
while (true) {
86
try {
87
const { version } = await hub.system.getCustomize(["version"]);
88
logger.debug("versionCheckLoop: ", { ...version, ourVersion });
89
if (version != null) {
90
const requiredVersion = compute_server_id
91
? (version.min_compute_server ?? 0)
92
: (version.min_project ?? 0);
93
if ((ourVersion ?? 0) < requiredVersion) {
94
logger.debug(
95
`ERROR: our CoCalc version ${ourVersion} is older than the required version ${requiredVersion}. \n\n** TERMINATING DUE TO VERSION BEING TOO OLD!!**\n\n`,
96
);
97
setTimeout(() => process.exit(1), 10);
98
}
99
}
100
} catch (err) {
101
logger.debug(`WARNING: problem getting version info from hub -- ${err}`);
102
}
103
await delay(VERSION_CHECK_INTERVAL);
104
}
105
}
106
107