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/compute-filesystem-cache.ts
Views: 687
1
/*
2
This is used by src/compute/compute/lib/filesystem-cache.
3
*/
4
5
import { join } from "path";
6
import { open, rm, stat } from "fs/promises";
7
import { exists } from "@cocalc/backend/misc/async-utils-node";
8
import type { ComputeFilesystemOptions } from "@cocalc/comm/websocket/types";
9
10
export default async function computeFilesystemCache(
11
opts: ComputeFilesystemOptions,
12
) {
13
const { func } = opts;
14
switch (func) {
15
case "filesToDelete":
16
return await filesToDelete(opts.allComputeFiles);
17
case "deleteWhiteouts":
18
return await deleteWhiteouts(opts.whiteouts);
19
default:
20
throw Error(`unknown command ${func}`);
21
}
22
}
23
24
// Given a path to a file that contains a list (one per line)
25
// of the files and on the compute server that are sync'd,
26
// return the ones that should be deleted from the compute server,
27
// because they were deleted locally.
28
async function filesToDelete(allComputeFiles: string) {
29
if (typeof allComputeFiles != "string") {
30
throw Error(
31
"filesToDelete takes the path to list of all files in the compute server as input",
32
);
33
}
34
if (!process.env.HOME) {
35
throw Error("HOME must be defined");
36
}
37
const file = await open(join(process.env.HOME, allComputeFiles));
38
const toDelete: string[] = [];
39
for await (const path of file.readLines()) {
40
const abspath = join(process.env.HOME, path);
41
if (!(await exists(abspath))) {
42
toDelete.push(path);
43
}
44
}
45
await file.close();
46
return toDelete;
47
}
48
49
async function deleteWhiteouts(whiteouts: { [path: string]: number }) {
50
if (!process.env.HOME) {
51
throw Error("HOME must be defined");
52
}
53
for (const path in whiteouts) {
54
try {
55
const abspath = join(process.env.HOME, path);
56
// if file already gone, this throws, which is fine
57
const { ctimeMs } = await stat(abspath);
58
if (ctimeMs >= whiteouts[path]) {
59
// file changed in the project *after* the delete, so don't delete.
60
continue;
61
}
62
await rm(join(process.env.HOME, path), { recursive: true });
63
} catch (_) {}
64
}
65
}
66
67