Skip to content

Commit 6060e75

Browse files
authored
Merge pull request #111 from lihsai0/fix/upload-resume
fix upload resume
2 parents f3154e8 + ccc9dd4 commit 6060e75

File tree

5 files changed

+174
-42
lines changed

5 files changed

+174
-42
lines changed

src/renderer/components/services/upload-manager.js

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -373,29 +373,6 @@ webModule.factory(UPLOAD_MGR_FACTORY_NAME, [
373373
progs = JSON.parse(data);
374374
} catch (e) {}
375375

376-
Object.entries(progs).forEach(([jobId, job]) => {
377-
if (!job.uploadedParts) {
378-
job.uploadedParts = [];
379-
}
380-
job.uploadedParts = job.uploadedParts.
381-
filter(part => part && part.PartNumber && part.ETag).
382-
map((part) => {
383-
return { partNumber: part.PartNumber, etag: part.ETag };
384-
});
385-
if (job.from && job.from.size && job.from.mtime) {
386-
if (fs.existsSync(job.from.path)) {
387-
const fileStat = fs.statSync(job.from.path);
388-
if (fileStat.size === job.from.size && job.from.mtime === fileStat.mtimeMs) {
389-
return;
390-
}
391-
}
392-
}
393-
job.uploadedParts = [];
394-
if (job.prog) {
395-
delete job.prog.loaded;
396-
}
397-
});
398-
399376
Object.entries(progs)
400377
.forEach(([jobId, briefJob]) => {
401378
if (!briefJob.from || !briefJob.from.size || !briefJob.from.mtime) {

src/renderer/models/job/download-job.test.ts

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@ jest.mock("electron", () => ({
99

1010
import { ipcRenderer } from "electron";
1111
import * as AppConfig from "@/const/app-config";
12-
import { IpcJobEvent, Status } from "./types";
12+
13+
import { EventKey, IpcJobEvent, Status } from "./types";
1314
import { downloadOptionsFromResumeJob } from "./_mock-helpers_/data";
1415

1516
import DownloadJob from "./download-job";
1617

17-
describe("test models/job/download-job.ts", () => {
18+
describe("test models/job/download-job.ts", () => {
1819
describe("test stop", () => {
1920
it("stop", () => {
2021
const downloadJob = new DownloadJob(downloadOptionsFromResumeJob);
@@ -90,4 +91,64 @@ describe("test models/job/download-job.ts", () => {
9091
downloadJob.stop();
9192
});
9293
});
94+
95+
describe("test resume download job", () => {
96+
it("getInfoForSave()", () => {
97+
const downloadJob = new DownloadJob(downloadOptionsFromResumeJob);
98+
99+
// stat
100+
const fakeProgressTotal = 1024;
101+
const fakeProgressResumable = true;
102+
downloadJob.startDownload(null, {
103+
key: EventKey.Stat,
104+
data: {
105+
progressTotal: fakeProgressTotal,
106+
progressResumable: fakeProgressResumable,
107+
},
108+
});
109+
expect(downloadJob.prog.total).toBe(fakeProgressTotal);
110+
expect(downloadJob.prog.resumable).toBe(fakeProgressResumable);
111+
112+
// progress
113+
const fakeProgressLoaded = 512;
114+
downloadJob.startDownload(null, {
115+
key: EventKey.Progress,
116+
data: {
117+
progressLoaded: fakeProgressLoaded,
118+
progressResumable: fakeProgressResumable,
119+
},
120+
});
121+
expect(downloadJob.prog.loaded).toBe(fakeProgressLoaded);
122+
expect(downloadJob.prog.resumable).toBe(fakeProgressResumable);
123+
124+
// part downloaded
125+
const lastDownloadedSize = downloadJob.prog.loaded;
126+
const fakeDownloadedSize = 512;
127+
downloadJob.startDownload(null, {
128+
key: EventKey.PartDownloaded,
129+
data: {
130+
size: fakeDownloadedSize,
131+
},
132+
});
133+
expect(downloadJob.prog.loaded).toBe(lastDownloadedSize + fakeDownloadedSize);
134+
135+
// info should in disk
136+
expect(downloadJob.getInfoForSave())
137+
.toEqual({
138+
storageClasses: downloadOptionsFromResumeJob.storageClasses,
139+
region: downloadOptionsFromResumeJob.region,
140+
to: downloadOptionsFromResumeJob.to,
141+
from: downloadOptionsFromResumeJob.from,
142+
backendMode: downloadOptionsFromResumeJob.backendMode,
143+
144+
prog: {
145+
loaded: downloadJob.prog.loaded,
146+
total: fakeProgressTotal,
147+
resumable: fakeProgressResumable,
148+
},
149+
status: Status.Waiting,
150+
message: "",
151+
});
152+
});
153+
})
93154
});

src/renderer/models/job/download-job.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -335,17 +335,20 @@ export default class DownloadJob extends Base {
335335

336336
getInfoForSave() {
337337
return {
338+
// read-only info
338339
storageClasses: this.options.storageClasses,
339340
region: this.options.region,
340341
to: this.options.to,
341342
from: this.options.from,
343+
backendMode: this.options.backendMode,
344+
domain: this.options.domain,
345+
346+
// real-time info
342347
prog: {
343348
loaded: this.prog.loaded,
344349
total: this.prog.total,
345350
resumable: this.prog.resumable
346351
},
347-
backendMode: this.options.backendMode,
348-
domain: this.options.domain,
349352
status: this.status,
350353
message: this.message,
351354
};

src/renderer/models/job/upload-job.test.ts

Lines changed: 85 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ jest.mock("electron", () => ({
1010
import { ipcRenderer } from "electron";
1111
import * as AppConfig from "@/const/app-config"
1212

13-
import { IpcJobEvent, Status } from "./types";
13+
import { EventKey, IpcJobEvent, Status } from "./types";
1414
import { uploadOptionsFromNewJob } from "./_mock-helpers_/data";
1515

1616
import UploadJob from "./upload-job";
1717

18-
describe("test models/job/upload-job.ts", () => {
18+
describe("test models/job/upload-job.ts", () => {
1919
describe("test stop", () => {
2020
it("stop", () => {
2121
const uploadJob = new UploadJob(uploadOptionsFromNewJob);
@@ -94,4 +94,87 @@ describe("test models/job/upload-job.ts", () => {
9494
uploadJob.stop();
9595
});
9696
});
97+
98+
describe("test resume upload job", () => {
99+
it("getInfoForSave()", () => {
100+
const uploadJob = new UploadJob(uploadOptionsFromNewJob);
101+
uploadJob.on('partcomplete', (data) => {
102+
uploadJob.uploadedId = data.uploadId;
103+
uploadJob.uploadedParts[data.part.partNumber] = data.part;
104+
return false;
105+
})
106+
107+
// stat
108+
const fakeProgressTotal = 1024;
109+
const fakeProgressResumable = true;
110+
uploadJob.startUpload(null, {
111+
key: EventKey.Stat,
112+
data: {
113+
progressTotal: fakeProgressTotal,
114+
progressResumable: fakeProgressResumable,
115+
},
116+
});
117+
expect(uploadJob.prog.total).toBe(fakeProgressTotal);
118+
expect(uploadJob.prog.resumable).toBe(fakeProgressResumable);
119+
120+
// progress
121+
const fakeProgressLoaded = 512;
122+
uploadJob.startUpload(null, {
123+
key: EventKey.Progress,
124+
data: {
125+
progressLoaded: fakeProgressLoaded,
126+
progressResumable: fakeProgressResumable,
127+
},
128+
});
129+
expect(uploadJob.prog.loaded).toBe(fakeProgressLoaded);
130+
expect(uploadJob.prog.resumable).toBe(fakeProgressResumable);
131+
132+
// part uploaded
133+
const fakeUploadedId = 'fakeUploadId';
134+
const fakeUploadedPart = {
135+
partNumber: 0,
136+
etag: 'fakeETag',
137+
};
138+
uploadJob.startUpload(null, {
139+
key: EventKey.PartUploaded,
140+
data: {
141+
uploadId: fakeUploadedId,
142+
part: fakeUploadedPart,
143+
},
144+
});
145+
expect(uploadJob.uploadedParts.length).toBe(1);
146+
expect(uploadJob.uploadedId).toBe(fakeUploadedId);
147+
expect(uploadJob.uploadedParts).toEqual([
148+
fakeUploadedPart,
149+
]);
150+
151+
// info should in disk
152+
expect(uploadJob.getInfoForSave({}))
153+
.toEqual({
154+
from: uploadOptionsFromNewJob.from,
155+
156+
backendMode: uploadOptionsFromNewJob.backendMode,
157+
overwrite: uploadOptionsFromNewJob.overwrite,
158+
to: uploadOptionsFromNewJob.to,
159+
region: uploadOptionsFromNewJob.region,
160+
storageClassName: uploadOptionsFromNewJob.storageClassName,
161+
storageClasses: uploadOptionsFromNewJob.storageClasses,
162+
163+
prog: {
164+
loaded: fakeProgressLoaded,
165+
total: fakeProgressTotal,
166+
resumable: fakeProgressResumable,
167+
},
168+
status: Status.Waiting,
169+
uploadedId: fakeUploadedId,
170+
uploadedParts: [
171+
{
172+
PartNumber: fakeUploadedPart.partNumber,
173+
ETag: fakeUploadedPart.etag,
174+
},
175+
],
176+
message: "",
177+
});
178+
});
179+
});
97180
});

src/renderer/models/job/upload-job.ts

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -355,29 +355,37 @@ export default class UploadJob extends Base {
355355
getInfoForSave({
356356
from
357357
}: {
358-
from: {
359-
size: number,
360-
mtime: number,
358+
from?: {
359+
size?: number,
360+
mtime?: number,
361361
}
362362
}) {
363363
return {
364-
storageClasses: this.options.storageClasses,
365-
region: this.options.region,
366-
to: this.options.to,
367364
from: {
368365
...this.options.from,
369366
...from,
370367
},
371-
prog: this.options.prog,
372-
status: this.options.status,
373-
message: this.options.message,
374-
uploadedId: this.options.uploadedId,
375-
uploadedParts: this.options.uploadedParts.map((part) => {
376-
return { PartNumber: part.partNumber, ETag: part.etag };
377-
}),
368+
369+
// read-only info
370+
storageClasses: this.options.storageClasses,
371+
region: this.options.region,
372+
to: this.options.to,
378373
overwrite: this.options.overwrite,
379374
storageClassName: this.options.storageClassName,
380375
backendMode: this.options.backendMode,
376+
377+
// real-time info
378+
prog: {
379+
loaded: this.prog.loaded,
380+
total: this.prog.total,
381+
resumable: this.prog.resumable
382+
},
383+
status: this.status,
384+
message: this.message,
385+
uploadedId: this.uploadedId,
386+
uploadedParts: this.uploadedParts.map((part) => {
387+
return { PartNumber: part.partNumber, ETag: part.etag };
388+
}),
381389
};
382390
}
383391
}

0 commit comments

Comments
 (0)