deno
deno copied to clipboard
Failure to release resource with `FsFile.close()` in the `Symbol.AsyncIterator`
Version: Deno x.x.x
deno 1.42.4 (release, aarch64-apple-darwin)
v8 12.3.219.9
typescript 5.4.3
I released resource with fd.close() once AsyncIterator has completed the iteration. However, there are some following issues:
done FsFile {}
error: Uncaught (in promise) BadResource: Bad resource ID
fd.close();
^
at FsFile.close (ext:deno_fs/30_fs.js:743:10)
at Object.next (file:///Users/feiwu/Project/deno/grammY/index.ts:18:32)
at eventLoopTick (ext:core/01_core.js:168:7)
at async stream (file:///Users/feiwu/Project/deno/grammY/index.ts:29:33)
But, it still exists and has not been released when I print fd(FsFile).
The source code is as follow:
async function main() {
const fd = await Deno.open("README.md");
const reader = fd.readable.getReader();
const asyncIterator = {
[Symbol.asyncIterator]() {
return {
async next() {
while (true) {
const { value, done } = await reader.read();
if (done) {
console.log("done", fd);
fd.close()
}
return { value, done };
}
},
};
},
} as AsyncIterable<Uint8Array>;
const iterator = asyncIterator[Symbol.asyncIterator]();
while (true) {
const { value, done } = await iterator.next();
if (done) break;
console.log(value);
}
}
Deno has already closed the file when the reader returns { done: true }, so when you call fd.close() it throws an error as you're trying to close the file again.
It should also be noted fd.readable is already async iterable, so you can just use it directly:
const iterator = fd.readable[Symbol.asyncIterator]();
Deno has already closed the file when the reader returns { done: true }, so when you call fd.close() it throws an error as you're trying to close the file again.
If according to what you said, fd should have been released when the function ended, but the fact is that it can still be accessed.
Delete if (done) ..., then add console.log(fd) in the function ended.
If according to what you said, fd should have been released when the function ended, but the fact is that it can still be accessed.
This is just how JS works, as long as a variable is in scope you can access it. There is no concept of destructors in JS, instead you simply let the garbage collector remove the object when it is no longer referenced.
This does not mean the file isn't closed, it is, it's just the wrapper object will throw errors if you try to call any of the methods (including .close).
This does not mean the file isn't closed, it is, it's just the wrapper object will throw errors if you try to call any of the methods (including .close).
Thank you, bro, I get it. But why is there no documention to explain all of this?
This is how all other APIs work - feel free to open a PR to improve the docs here :)
@lucacasonato Thank you, I'm trying to improve it.