Skip to content

Commit 245dea4

Browse files
committed
fix(nodejs-write-stream): file handler is garbage collected when exception is thrown
1 parent f6e0935 commit 245dea4

1 file changed

Lines changed: 22 additions & 4 deletions

File tree

src/download/download-engine/streams/download-engine-write-stream/download-engine-write-stream-nodejs.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@ const DEFAULT_OPTIONS: DownloadEngineWriteStreamOptionsNodeJS = {
1717
const NOT_ENOUGH_SPACE_ERROR_CODE = "ENOSPC";
1818

1919
export default class DownloadEngineWriteStreamNodejs extends BaseDownloadEngineWriteStream {
20+
private static _allFd = new Set<FileHandle>();
21+
private static _finalizationRegistry = new FinalizationRegistry(async (fd: FileHandle) => {
22+
if (fd.fd != null) {
23+
await fd.close();
24+
}
25+
DownloadEngineWriteStreamNodejs._allFd.delete(fd);
26+
});
27+
2028
private _fd: FileHandle | null = null;
2129
private _fileWriteFinished = false;
2230
public readonly options: DownloadEngineWriteStreamOptionsNodeJS;
@@ -35,7 +43,10 @@ export default class DownloadEngineWriteStreamNodejs extends BaseDownloadEngineW
3543

3644
return await retry(async () => {
3745
await fsExtra.ensureFile(this.path);
38-
return this._fd = await fs.open(this.path, this.options.mode);
46+
this._fd = await fs.open(this.path, this.options.mode);
47+
DownloadEngineWriteStreamNodejs._allFd.add(this._fd);
48+
DownloadEngineWriteStreamNodejs._finalizationRegistry.register(this, this._fd, this);
49+
return this._fd;
3950
}, this.options.retry);
4051
});
4152
}
@@ -103,8 +114,7 @@ export default class DownloadEngineWriteStreamNodejs extends BaseDownloadEngineW
103114
return JSON.parse(metadataString);
104115
} catch {}
105116
} finally {
106-
this._fd = null;
107-
await fd.close();
117+
await this.close();
108118
}
109119
}
110120

@@ -115,7 +125,15 @@ export default class DownloadEngineWriteStreamNodejs extends BaseDownloadEngineW
115125
}
116126

117127
override async close() {
118-
await this._fd?.close();
128+
if (!this._fd) {
129+
return;
130+
}
131+
132+
if (this._fd.fd != null) {
133+
await this._fd.close();
134+
}
135+
DownloadEngineWriteStreamNodejs._allFd.delete(this._fd);
136+
DownloadEngineWriteStreamNodejs._finalizationRegistry.unregister(this);
119137
this._fd = null;
120138
}
121139
}

0 commit comments

Comments
 (0)