Skip to content

Commit d8f0a48

Browse files
committed
feat: implement RenewFetchError for improved fetch handling and update download engine methods for cloning
1 parent 8d7d2dd commit d8f0a48

7 files changed

Lines changed: 26 additions & 10 deletions

File tree

src/download/download-engine/download-file/download-engine-file.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ export default class DownloadEngineFile extends EventEmitter<DownloadEngineFileE
252252

253253
const streamPromises = new Set<Promise<void>>();
254254

255-
for (let i = this._progress.part; i < this.file.parts.length && !this.options.skipExisting; i++) {
255+
for (let i = this._progress.part; i < this.file.parts.length; i++) {
256256
if (this._closed) return;
257257
// If we are starting a new part, we need to reset the progress
258258
if (i > this._progress.part || !this._activePart.acceptRange) {
@@ -470,11 +470,10 @@ export default class DownloadEngineFile extends EventEmitter<DownloadEngineFileE
470470
this.emit0("closed");
471471
}
472472

473-
public finished(comment?: string) {
474-
if (comment) {
475-
this.options.comment = pushComment(comment, this.options.comment);
476-
}
477-
this._downloadStatus = DownloadStatus.Finished;
473+
public markAsCloned() {
474+
this.options.comment = pushComment("cloned", this.options.comment);
475+
this._progressStatus.downloadFlags!.push(DownloadFlags.Cloned);
476+
this._progress.part = this.file.parts.length - 1;
478477
}
479478

480479
public [Symbol.dispose]() {

src/download/download-engine/download-file/progress-status-file.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export enum DownloadStatus {
2828

2929
export enum DownloadFlags {
3030
Existing = "Existing",
31+
Cloned = "Cloned",
3132
DownloadSequence = "DownloadSequence"
3233
}
3334

src/download/download-engine/engine/download-engine-nodejs.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ export default class DownloadEngineNodejs<T extends DownloadEngineWriteStreamNod
6666
await fs.unlink(this.options.writeStream.path);
6767
} catch { }
6868
await reflinkFile(this.options.fullPartURLInternal[0].url, this.options.writeStream.path);
69-
this._engine.finished("cloned");
69+
this._engine.markAsCloned();
7070
} catch { }
7171
};
7272

src/download/download-engine/streams/download-engine-fetch-stream/base-download-engine-fetch-stream.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {sleepPromise} from "../../utils/sleepPromise.js";
88
import HttpError from "./errors/http-error.js";
99
import StatusCodeError from "./errors/status-code-error.js";
1010
import {retryAsyncStatementSimple} from "./utils/retry-async-statement.js";
11+
import {RenewFetchError} from "./errors/RenewFetchError.js";
1112

1213
export const MIN_LENGTH_FOR_MORE_INFO_REQUEST = 1024 * 1024 * 3; // 3MB
1314

@@ -280,6 +281,14 @@ export default abstract class BaseDownloadEngineFetchStream extends EventEmitter
280281
callback(...args);
281282
});
282283
} catch (error: any) {
284+
if (this.paused){
285+
await this.paused;
286+
287+
if (error instanceof RenewFetchError){
288+
continue;
289+
}
290+
}
291+
283292
if (error?.name === "AbortError" && this.aborted) return;
284293

285294
this.errorCount.value++;

src/download/download-engine/streams/download-engine-fetch-stream/download-engine-fetch-stream-fetch.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import BaseDownloadEngineFetchStream, {
88
} from "./base-download-engine-fetch-stream.js";
99
import {EmptyStreamTimeoutError} from "./errors/EmptyStreamTimeoutError.js";
1010
import InvalidContentLengthError from "./errors/invalid-content-length-error.js";
11+
import {RenewFetchError} from "./errors/RenewFetchError.js";
1112
import StatusCodeError from "./errors/status-code-error.js";
1213
import {browserCheck} from "./utils/browserCheck.js";
1314
import {parseContentDisposition} from "./utils/content-disposition.js";
@@ -161,8 +162,8 @@ export default class DownloadEngineFetchStreamFetch extends BaseDownloadEngineFe
161162
if (this.paused) {
162163
clearWatchdog();
163164
smartSplit.closeAndSendLeftoversIfLengthIsUnknown();
165+
reject(new RenewFetchError("Fetch paused"));
164166
this._activeController?.abort();
165-
this.paused.then(resolve);
166167
return;
167168
}
168169

src/download/download-engine/streams/download-engine-fetch-stream/download-engine-fetch-stream-xhr.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ export default class DownloadEngineFetchStreamXhr extends BaseDownloadEngineFetc
7272
let aborted = false;
7373

7474
const clearStreamNotResponding = () => {
75+
lastChunkReceived = Date.now();
76+
waitingForChunk = false;
7577
if (streamNotRespondedInTime) {
7678
streamNotRespondedInTime = false;
7779
this.emit0("streamNotRespondingOff");
@@ -106,8 +108,6 @@ export default class DownloadEngineFetchStreamXhr extends BaseDownloadEngineFetc
106108
};
107109

108110
xhr.onload = () => {
109-
lastChunkReceived = Date.now();
110-
waitingForChunk = false;
111111
clearStreamNotResponding();
112112
clearWatchDog();
113113

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import FetchStreamError from "./fetch-stream-error.js";
2+
3+
// error used to signal that fetch should be renewed, this is used internally
4+
export class RenewFetchError extends FetchStreamError {
5+
6+
}

0 commit comments

Comments
 (0)