I'm too dumb for Zig's new IO interface
83 points by janerik
83 points by janerik
Never do this:
defer tls_client.end() catch {};
The language is trying to help you diligently check all the errors, but this code explicitly catches the error and then disregards it. This is obviously a bug.
To make it work: don’t forget to flush. :-) After writing to the tls_client’s writer:
try tls_client.writer.flush();
try writer.interface.flush();
Also reader.stream
just pushes whatever is in the buffer. As the server probably hasn’t answered by then, something like streamDelimiterLimit
is more what is wanted – wait until the delimiter shows up. And finally the final writer is – depending on the use case – probably not necessary, just takeDelimiter
to see the data in the reader’s buffer directly.
I think mostly this is just a case of missing docs which will surely be written eventually.
Buffering is a first class citizen of the new Io interface - who needs composition?
I don’t understand this – buffering is orthogonal to composition, no? In this case it even helps: TLS shouldn’t need to handle more bytes than max_ciphertext_inner_record_len
(I think this is the correct variable for the writer, but I’m not sure about the TLS protocol) in one message, so have a buffer this size. Once you want to write more, the buffer gets automatically packed into one TLS message and cleared for the next message. Neither the implementation of the TLS writer has to handle this (it only sees one single write with the buffer’s content) nor the user needs to handle this (they write as much as they want – and hopefully don’t forget to flush.)
Your suggestion has been implemented: https://github.com/karlseguin/smtp_client.zig/commit/857d6f7be55cc878eb55b87dfae2539f05eda14d
This transition to IO seems like zig’s equivalent to Python 3 - everything is going to break, and be worse for a good while. But that’s appropriate for a language not at 1.0
Doubtful. Zig breaks stuff all the time and has few users. Dramatically different situation from where Python was.
I don’t follow Zig’s development. https://ziglang.org/download/0.15.1/release-notes.html#Motivation feels vague to me, and linking to a lengthy video isn’t very clarifying. Still, I skimmed through it to get a sense of it.
Zig’s approach seems to require users to explicitly call flush for any writes.
This reminds me of a similar issue in LLVM’s raw_svector_ostream
. Before a 2015 commit https://github.com/llvm/llvm-project/commit/3d1173ba1a53cab08ed2c33e47dd617df77a914b ,
it only called flush at the end, which was efficient. That commit changed this, leading to unnecessarily slow performance.
To not break existing users, the 2024 pull request https://github.com/llvm/llvm-project/pull/97704 tries to implement a new interface, but the changes would cause significant churn.
TBH this reminds me of the pain of hooking up TLS in C, say, mbedTLS, which is an awfully low bar to clear. I know Zig is a low-level language but it should be able to do much better.
lol, I can’t even read it, yet understand (i am not a c person, like john cena)
I hear a lot of good things about zig, and from what I know it’s in early stage, so probably will get a few annoyances before it settles in
“A few” is an understatement.
does it mean zig gets a lot of changes?
ghostty is the only software I follow that uses zig or that I am aware of. So wonder how annoying is all changes/migrations one required to make
PS. How fan is making these updates? I am totally fine and happy when language introduces something new and cool while breaking the legacy code. However I will be furious if I have to do it constantly with very few benefits for upgrades
Ghostty guy here. Disclaimer for the rest of this: I haven’t done the writergate changes yet.
So wonder how annoying is all changes/migrations one required to make
We’ve used Zig since 0.10. It hasn’t been too bad, so far. You definitely WILL have to make changes to your program each Zig release, but Zig is very up front about being at that stage in its life (the warning is in every release notes). The biggest annoyance has been upstream library dependencies.
Zig changes rapidly enough that we had a policy for no dependencies we didn’t control until very recently. It was too risky to be reliant on a dependency that blocks your ability to update and grab language fixes. As a result, we built and owned all of our own dependencies.
Since the 0.13, 0.14 releases, the language changes have been a lot more tractable and less annoying. As such, we’ve brought on some dependencies we don’t control. However, we still require a direct line to talk to the maintainers. Usually before adopting a dependency, I’ll shoot them an email or find them on their preferred discussion medium. I give them a heads up that we want to adopt the dep, ask how they feel about time to update Zig versions, etc.
This is all open source so there are no guarantees, but I want to know what to expect.
It’s been hit or miss. You have to go in expect this at this time for Zig.
Beyond this though, Zig has been an absolute joy. Love it.
Switched to Ghostty recently, loving it! Thanks for your hard work, and I hope to get into Zig once it’s a little more stable for dummies like me :P