await writer.write(buffer) never resolves on Deno.Command
Hiho. I'm creating a
Deno.Command
that writes a buffer to vipsthumbnail
via stdin (and reads the result via stdout).
It works most of the time, but sometimes gets stuck on await writer.write(source);
. Source is the result of await Deno.readFile(path)
.
The big problem is that there is no error, the writer.write() promise is just never resolved. So I have no idea how to debug, catch errors or even cancel this after timeout or something.
I can process a couple of files (all with a new Deno.Command
) but then after a few files it gets stuck and the promise never resolves.
Any ideas how to begin solving what the problem is.
18 Replies
Are you sure that vipsthumbnail is actually reading stdin if stdin hasn't closed?
If the output buffer fills up,
writer.write()
will block.
you could try await Promise.all([writer.write(), writer.close()])
to find outhm. no I'm not sure :) it appears to read, I can process a couple of files just fine. is it possible vipsthumbnail does read stdin, but then stops reading it when it encounters some kind of error parsing a certain file?
anything's possible, of course. All programs have bugs.
this doesnt seem to help with getting it unstuck
however, when vipsthumbnail exits without reading pending stdin, I would have expected
await writer.write
to throw.the weird thing is that vipsthumbnail prints stuff to stderr, like _file "" does not exist, but then it still gives a proper result. maybe it first tries to open a file named "stdin", prints some errors, and only then reverts to the code path that actually reads stdin. (you are supposed to call it with "stdin" in place of the input file name argument)
might be unrelated but this sounds similar to this old problem
https://discord.com/channels/684898665143206084/1074484890562736188/1074682730073313340
how would I go about writing a timeout to abort the
writer.write()
if it takes x amount of timeWhat if you throw
cmd.status()
into the Promise.all? Do you get a zero exit code? await Promise.all([writer.write(source), writer.close(), cmd.status]);
just makes it fail on the first file (same result, never resolves)This uses Deno.run but it should be the same general logic
https://github.com/jeff-hykin/quickr/blob/139ebd639bb474be1b0b77a3c3f273ca36c93d6d/main/run.js#L592C23-L592C23
GitHub
quickr/main/run.js at 139ebd639bb474be1b0b77a3c3f273ca36c93d6d · je...
💾 📦 Tools for Deno. Contribute to jeff-hykin/quickr development by creating an account on GitHub.
Copilot to the rescue, it wrote this nicely working timeout function, so at least I can move on when it fails.
did you not actually want to cancel the process on timeout?
oh yeah I should do that, close everything before returning
okay. if you try to kill a process that already stopped it'll get an error. The code I linked handles that case, although you'll have to integrate it with the write-timeout code