4 ms·
Author here. I finally got it working. I had to flush both the encrypted writer and then the stream writer. There was also some issues with reading. Streaming
by latch 1y ago
Author here.
I finally got it working. I had to flush both the encrypted writer and then the stream writer. There was also some issues with reading. Streaming works, but it'll always return 0 on the first read because Writer.Fixed doesn't implement sendFile, and thus after the first call, it internally switches from streaming mode to reading mode (1) and then things magically work.
Currently trying to get compression re-enabled in my websocket library.
(1) https://github.com/ziglang/zig/blob/47a2f2ddae9cc47ff6df7a71060bbb3f5f20f2e8/lib/std/fs/File.zig#L1318 https://github.com/ziglang/zig/blob/47a2f2ddae9cc47ff6df7a71...
- dchest 1y agoHa, "Don't Forget to Flush" https://www.youtube.com/watch?v=f30PceqQWko https://www.youtube.com/watch?v=f30PceqQWko
- jenadine 1y agoThat's why I like RAII.
- bnolsen 1y agoHidden control flow violates the zig manifesto.
- AndyKelley 1y agoIt's a bug to flush (fallible operation) in a destructor (infallible operation).
- oconnor663 1y agoI know you've thought carefully about these issues, but still it can't be that simple, can it? Closing a file or a socket is a fallible operation too.
- AndyKelley 1y agoWrong.
- MrResearcher 1y agoWhy is he wrong? Here's an excerpt from the close(2) syscall description: RETURN VALUE close() returns zero on success. On error, -1 is returned, and errno is set to indicate the error. ERRORS EBADF fd isn't a valid open file descriptor. EINTR The close() call was interrupted by a signal; see signal(7). EIO An I/O error occurred. ENOSPC EDQUOT On NFS, these errors are not normally reported against the first write which exceeds the available storage space, but instead against a subsequent write(2), fsync(2), or close(). See NOTES for a discussion of why close() should not be retried after an error. It obviously can fail due to a multitude of reasons.
- AndyKelley 1y agoIt's unfortunate that the original authors of this interface didn't understand how important infallibility is to resource deallocation, and it's unfortunate that NFS authors didn't think carefully about this at all, but if you follow the advice of the text you pasted and read the section about how you can't retry close() after an error, it is clear that close is, in fact, a fundamentally infallible operation.
- MrResearcher 1y agoIf the flush (syscall) fails, it's not possible to recover in user space, therefore the only sensible option is to abort() immediately. It's not even safe to perror("Mayday, mayday, flush() failed"), you must simply abort(). And, the moment you start flushing correctly: if(flush(...)) { abort(); }, it becomes infallible from the program's point of view, and can be safely invoked in destructors. File closure operations, on the other hand, do have legitimate reasons to fail. In one of my previous adventures, we were asking the operator to put the archival tape back, and then re-issuing the close() syscall, with the driver checking that the tape is inserted and passing the control to the mechanical arm for further positioning of the tape, all of that in the drivers running in the kernel space. The program actually had to retry close() syscalls, and kept asking the operator to handle the tape (there were multiple scenarios for the operator how to proceed).
- tempodox 1y agoWhatever happened to the principle of least surprise?
- DrewADesign 1y agoUnsurprisingly, it’s occasionally disregarded—seemingly when you least expect it.
- selfmodruntime 1y agoGoing from the previous interface to what ever this is, is certainly something. Yeesh.