Skip to content

Commit 1ae402b

Browse files
committed
implemented upload via drag-n-drop of tiles to compute server directly that works, but it's not a good implementation
1 parent 7fae627 commit 1ae402b

File tree

1 file changed

+61
-11
lines changed

1 file changed

+61
-11
lines changed

src/packages/project/upload.ts

Lines changed: 61 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import {
2323
unlink,
2424
} from "node:fs/promises";
2525
import { join } from "node:path";
26+
import { handleCopy } from "@cocalc/sync-fs/lib/handle-api-call";
2627

2728
const { F_OK, W_OK, R_OK } = fs_constants;
2829

@@ -133,6 +134,8 @@ export default function init(): Router {
133134
parseInt(fields.dztotalchunkcount),
134135
chunkFullPath,
135136
dest,
137+
dest_dir,
138+
compute_server_id,
136139
);
137140

138141
res.send("received upload:\n\n");
@@ -157,6 +160,8 @@ async function handle_chunk_data(
157160
total: number,
158161
chunk: string,
159162
dest: string,
163+
dest_dir: string,
164+
compute_server_id: number,
160165
): Promise<void> {
161166
const temp = dest + ".partial-upload";
162167
if (index === 0) {
@@ -170,20 +175,65 @@ async function handle_chunk_data(
170175
}
171176
// if it's the last chunk, move temp to actual file.
172177
if (index === total - 1) {
173-
await moveFile(temp, dest);
178+
await moveFile(temp, dest, dest_dir, compute_server_id);
174179
}
175180
}
176181

177-
async function moveFile(src: string, dest: string): Promise<void> {
182+
async function moveFile(
183+
src: string,
184+
dest: string,
185+
dest_dir?: string,
186+
compute_server_id?: number,
187+
): Promise<void> {
178188
try {
179-
await rename(src, dest);
180-
} catch (_) {
181-
// in some cases, e.g., cocalc-docker, this happens:
182-
// "EXDEV: cross-device link not permitted"
183-
// so we just try again the slower way. This is slightly
184-
// inefficient, maybe, but more robust than trying to determine
185-
// if we are doing a cross device rename.
186-
await copyFile(src, dest);
187-
await unlink(src);
189+
if (compute_server_id) {
190+
// The final destination of this file upload is a compute server.
191+
// We copy the temp file (src) to the compute server, then remove
192+
// the temp file.
193+
// TODO: it would obviously be much more efficient to upload directly
194+
// to the compute server without going through cocalc at all. For
195+
// various reasons that is simply impossible in general, unfortunately.
196+
logger.debug("move temporary file to compute server", {
197+
src,
198+
dest,
199+
dest_dir,
200+
compute_server_id,
201+
});
202+
203+
// input to handleCopy must be relative to home directory,
204+
// but src and dest are absolute paths got by putting HOME
205+
// in the front of them:
206+
const { HOME } = process.env;
207+
if (!HOME) {
208+
throw Error("HOME env var must be set");
209+
}
210+
await rename(src, dest);
211+
await handleCopy({
212+
event: "copy_from_project_to_compute_server",
213+
compute_server_id,
214+
paths: [dest.slice(HOME.length + 1)],
215+
dest: dest_dir,
216+
});
217+
return;
218+
}
219+
220+
logger.debug("move temporary file to dest", {
221+
src,
222+
dest,
223+
});
224+
try {
225+
await rename(src, dest);
226+
} catch (_) {
227+
// in some cases, e.g., cocalc-docker, this happens:
228+
// "EXDEV: cross-device link not permitted"
229+
// so we just try again the slower way. This is slightly
230+
// inefficient, maybe, but more robust than trying to determine
231+
// if we are doing a cross device rename.
232+
await copyFile(src, dest);
233+
}
234+
} finally {
235+
try {
236+
await unlink(src);
237+
} catch (_) {}
188238
}
189239
}

0 commit comments

Comments
 (0)