Skip to content

Commit

Permalink
Use OPFS for file downloading (#169)
Browse files Browse the repository at this point in the history
  • Loading branch information
JustusFT authored Jun 21, 2023
1 parent 3bf21cf commit f170814
Show file tree
Hide file tree
Showing 16 changed files with 237 additions and 70 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
pkg/
/client/certs
/client/coverage
/client/test-report.xml
/client-e2e/test/files/sizes/
dist/
node_modules/
Expand Down
4 changes: 2 additions & 2 deletions client-e2e/scripts/generate-CI-test-files.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ if [ ! -d "./test/files/sizes" ]; then
mkdir ./test/files/sizes
fi
cd ./test/files/sizes
dd if=/dev/zero of=5MB bs=5000000 count=1
dd if=/dev/zero of=20MB bs=20000000 count=1
dd if=/dev/zero of=5MB.bin bs=5000000 count=1
dd if=/dev/zero of=20MB.bin bs=20000000 count=1
10 changes: 5 additions & 5 deletions client-e2e/scripts/generate-sized-test-files.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
if [ ! -d "/usr/src/app/test/files/sizes" ]; then
mkdir /usr/src/app/test/files/sizes
cd /usr/src/app/test/files/sizes
dd if=/dev/zero of=5MB bs=5000000 count=1
dd if=/dev/zero of=20MB bs=20000000 count=1
dd if=/dev/zero of=300MB bs=300000000 count=1
dd if=/dev/zero of=4.2GB bs=1000000 count=4200
dd if=/dev/zero of=4.3GB bs=1000000 count=4300
dd if=/dev/zero of=5MB.bin bs=5000000 count=1
dd if=/dev/zero of=20MB.bin bs=20000000 count=1
dd if=/dev/zero of=300MB.bin bs=300000000 count=1
dd if=/dev/zero of=4.2GB.bin bs=1000000 count=4200
dd if=/dev/zero of=4.3GB.bin bs=1000000 count=4300
fi
12 changes: 6 additions & 6 deletions client-e2e/test/specs/cancellation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ describe("Cancellation", () => {

await browser.getWindowHandle();

await Page.uploadFiles("./test/files/sizes/20MB");
await Page.uploadFiles("./test/files/sizes/20MB.bin");
const codeUrl = await Page.getCodeUrl();

await (await Page.cancelButton()).click();
Expand All @@ -27,7 +27,7 @@ describe("Cancellation", () => {
it("Sends the Sender back and show cancellation message, no message for Receiver", async function () {
await Page.open();
const sendWindow = await browser.getWindowHandle();
await Page.uploadFiles("./test/files/sizes/20MB");
await Page.uploadFiles("./test/files/sizes/20MB.bin");

const codeUrl = await Page.getCodeUrl();
const _receiveWindow = await browser.newWindow(codeUrl);
Expand All @@ -50,7 +50,7 @@ describe("Cancellation", () => {
it("Sends the Receiver and Sender back. The Sender gets an error message", async function () {
await Page.open();
const sendWindow = await browser.getWindowHandle();
await Page.uploadFiles("./test/files/sizes/20MB");
await Page.uploadFiles("./test/files/sizes/20MB.bin");

const codeUrl = await Page.getCodeUrl();
const _receiveWindow = await browser.newWindow(codeUrl);
Expand Down Expand Up @@ -78,7 +78,7 @@ describe("Cancellation", () => {
it("(after 5 sec.) Sends the Receiver and Sender back. The Sender gets an error message", async function () {
await Page.open();
const sendWindow = await browser.getWindowHandle();
await Page.uploadFiles("./test/files/sizes/20MB");
await Page.uploadFiles("./test/files/sizes/20MB.bin");

const codeUrl = await Page.getCodeUrl();
const _receiveWindow = await browser.newWindow(codeUrl);
Expand Down Expand Up @@ -112,7 +112,7 @@ describe("Cancellation", () => {
it("Sends the Receiver and Sender back. The Receiver gets an error message", async function () {
await Page.open();
const sendWindow = await browser.getWindowHandle();
await Page.uploadFiles("./test/files/sizes/20MB");
await Page.uploadFiles("./test/files/sizes/20MB.bin");
const codeUrl = await Page.getCodeUrl();

// Receiver
Expand Down Expand Up @@ -143,7 +143,7 @@ describe("Cancellation", () => {
it("Sends the Sender back with no message", async function () {
await Page.open();
const sendWindow = await browser.getWindowHandle();
await Page.uploadFiles("./test/files/sizes/20MB");
await Page.uploadFiles("./test/files/sizes/20MB.bin");
const codeUrl = await Page.getCodeUrl();

const _receiveWindow = await browser.newWindow(codeUrl);
Expand Down
2 changes: 1 addition & 1 deletion client-e2e/test/specs/pages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ describe("Check internal Pages", () => {
await Page.open();
// Sender
const _sendWindow = await browser.getWindowHandle();
await Page.uploadFiles("./test/files/sizes/20MB");
await Page.uploadFiles("./test/files/sizes/20MB.bin");
const codeUrl = await Page.getCodeUrl();

// Receiver
Expand Down
6 changes: 3 additions & 3 deletions client-e2e/test/specs/send-large-files.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,21 +45,21 @@ async function testTransferFailure(fileName: string, timeout?: number) {
describe("Send flow large files", () => {
describe("when uploading a file with the size of 300MB", () => {
it("will tell the user that the file is too large", async () => {
await testTransferFailure("sizes/300MB");
await testTransferFailure("sizes/300MB.bin");
});
});

describe("when uploading a file with the size of 4.2GB", () => {
it("will tell the user that the file is too large", async function () {
this.timeout(120000);
await testTransferFailure("sizes/4.2GB");
await testTransferFailure("sizes/4.2GB.bin");
});
});

describe("when uploading a file with the size of 4.3GB", () => {
it("will tell the user that the file is too large", async function () {
this.timeout(120000);
await testTransferFailure("sizes/4.3GB");
await testTransferFailure("sizes/4.3GB.bin");
});
});
});
4 changes: 2 additions & 2 deletions client-e2e/test/specs/send.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,15 @@ describe("Send flow", () => {
describe("when uploading a file with the size of 5MB", () => {
it("will transfer successfully", async () => {
// 100 sec.
await testTransferSuccess("sizes/5MB", 100000);
await testTransferSuccess("sizes/5MB.bin", 100000);
});
});

describe("when uploading a file with the size of 20MB", () => {
// TODO: enable, when speed issue fixed, currently fails with Firefox
it.skip("will transfer successfully", async () => {
// 100 sec.
await testTransferSuccess("sizes/20MB", 100000);
await testTransferSuccess("sizes/20MB.bin", 100000);
});
});

Expand Down
73 changes: 63 additions & 10 deletions client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"classnames": "^2.3.1",
"fastest-levenshtein": "^1.0.12",
"formik": "^2.2.9",
"nanoid": "^4.0.2",
"nosleep.js": "^0.12.0",
"react": "^18.0.0",
"react-dom": "^18.0.0",
Expand Down
2 changes: 2 additions & 0 deletions client/src/app/components/CodeInput.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ const emptyLine = String.fromCharCode(8203);

global.ResizeObserver = require("resize-observer-polyfill");

jest.mock("../util/downloader/downloader.ts");

// Sometimes tests fails on Github CI
jest.retryTimes(1);

Expand Down
22 changes: 7 additions & 15 deletions client/src/app/sagas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import streamSaver from "streamsaver";
import { Client, ReceiveResult, SendResult } from "../../pkg";
import { setError } from "./errorSlice";
import { NoSleep } from "./NoSleep";
import { close, createStream, write } from "./util/downloader/downloader";
import { makeProgressFunc } from "./util/makeProgressFunc";
import {
completeLoading,
completeTransfer,
requestCancelTransfer,
reset,
selectWormholeStatus,
setConsenting,
Expand Down Expand Up @@ -130,22 +130,14 @@ function* transfer(): any {
"wormhole/answerConsent"
);
if (consentPayload) {
const fileStream = streamSaver.createWriteStream(
receiveResult.get_file_name(),
{
size: Number(receiveResult.file_size),
}
);
writer = fileStream.getWriter();
const fileName = receiveResult.get_file_name();
const stream = yield createStream(receiveResult.get_file_name());
yield pkg.download_file(
receiveResult,
{
write: (x: unknown) =>
writer!.write(x).catch((e) => {
// If `writer.write` throws, the user cancelled the download through the browser's download manager.
console.error("Failed to write:", e);
transferChannel.put(requestCancelTransfer());
}),
write: (x: Uint8Array) => {
write(stream, x);
},
progress: makeProgressFunc((sentBytes, totalBytes) => {
transferChannel.put(
setTransferProgress([sentBytes, totalBytes])
Expand All @@ -154,7 +146,7 @@ function* transfer(): any {
},
cancel
);
yield writer.close();
yield close(stream);
yield put(completeTransfer());
} else {
yield pkg.reject_file(receiveResult);
Expand Down
1 change: 1 addition & 0 deletions client/src/app/util/downloader/__mocks__/downloader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// no need for a mock implementation (yet)
17 changes: 17 additions & 0 deletions client/src/app/util/downloader/cleanerWorker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
async function cleanup() {
const directoryHandle = await navigator.storage.getDirectory();
const now = Date.now();
// @ts-ignore
for await (const [filename, handle] of directoryHandle.entries()) {
const file: File = await handle.getFile();
if (now >= file.lastModified + 60000) {
directoryHandle.removeEntry(filename);
}
}
}

cleanup();

setInterval(() => {
cleanup();
}, 30000);
Loading

0 comments on commit f170814

Please sign in to comment.