How I turned Zig into my favorite language to write network programs in
55 points by andyferris
55 points by andyferris
I think composable stream interfaces are a thing of beauty.
I fondly remember working with Java in the early 2000s and how easy it was to convert filesystem-based code to network-based code when the receiving end wanted InputStreams and testing was so easy with a fixed byte array based ByteArrayInputStream.
Agreed! It's one of the early things I loved about Go's io.Reader and io.Writer, mixed with implicit interfaces.
I am curious how this will gel with the incoming async io refresh in Zig (0.16?)
Per Readme on github:
Streams implement the standard std.Io.Reader and std.Io.Writer interfaces, so you can use external libraries, that were never written with asynchronous I/O in mind and they will just work. Additionally, when Zig 0.16 is released with the std.Io interface, I will implement that as well, allowing you to use the entire standard library with this runtime.
For blitting structures across the network? I think the best choice is something with binary pattern matching, which is unfortunately not many languages. But it does make dealing with bit-level manipulation trivial. Your best bet for that is something BEAM.
BEAM is almost always the right answer for network programming.
I would be curious to explore that alley. Would you have any good recommendations regarding network programming with the beam ?
I need to free up time to play with Zig more seriously. I've been following it and related projects closely for a couple of years, have used zig cc for easier cgo cross-compilation, but haven't made anything substantial.
Maybe this or the upcoming I/O changes will get me off my ass. :)
Writing a web server in a non memory safe language doesn't strike me as a good idea
What areas of safety are you most concerned about there? As a quick mention, Zig does have runtime bounds checking on array access.
That was my primary concern, TIL! Still even a small memory leak can be the target of a DoS attack.
Assuming you can isolate an entire request path in testing, you can pass different allocators to detect memory leaks. Take a look at std.testing.allocator and std.heap.DebugAllocator. I believe the GeneralPurposeAllocator can be configured to detect leaks as well. The design and tooling here is really flexible!
Edit: Or, even better, consider using static allocation on initialization. Each request gets a fixed amount of working memory space it can use. Anything beyond that fails the request. Zig makes this a lot easier than other languages.
std.heap.GeneralPurposeAllocator is std.heap.DebugAllocator, IIRC, it was re-named in Zig 0.14(? or maybe 0.15.1).