Hi all! Allen Wyma of Rustacean Station had me on the podcast to talk about Rust at Cloudflare. We cover why and how Cloudflare started using Rust, how my team specifically works with Rust, and how Cloudflare works. We also go on a big tangent about social security numbers. Give the episode a listen if you'd like.
Say you're running a long-lived program, like a server. Let's say the server needs to read some files from disk, like certificates or keys. Every so often, the certificates change, so your server has to reload them. How do you tell the server to reload those files? The traditional way is to use Unix signals. Your server listens for a particular signal, like
SIGUSR1 (user-defined signal #1) or
SIGHUP (hangup signal), and can execute whatever code you programmed in when the signal is received. So, your code waits for the appropriate signal, receives it, then reloads the certs.
This approach works fine, but it has some usability problems that came up at work. So, my coworkers have been thinking about better ways to do this. I wanted to blog about one such way, and see if anyone has better ideas.
Reflecting on the things I liked in 2022. I started writing this in December 2022 and completely forgot to finish it until February next year.
In case you didn't hear, comedy is now legal on Twitter but accounts engaged in parody must include “parody” in their name, not just in bio. Of course, this only made everyone double down. So yesterday, I changed my name to Rust Language and started posting misinformation.
The last week on twitter has basically been "the new 3rd grade substitute teacher can't control the class" and we're all misbehaving. I've changed my twitter back to my real name and face, so I've preserved my fake Rust tweets for posterity here.
I first learned Kubernetes ("k8s" for short) in 2018, when my manager sat me down and said "Cloudflare is migrating to Kubernetes, and you're handling our team's migration." This was slightly terrifying to me, because I was a good programmer and a mediocre engineer. I knew how to write code, but I didn't know how to deploy it, or monitor it in production. My computer science degree had taught me all about algorithms, data structures, type systems and operating systems. It had not taught me about containers, or ElasticSearch, or Kubernetes. I don't think I even wrote a single YAML file in my entire degree. I was scared of ops. I was terrified of Kubernetes.
Eventually I made it through and migrated all the Cloudflare Tunnel infrastructure from Marathon to Kubernetes. I didn't enjoy it, and I was way over my deadline, but I did learn a lot. Now it's 2022, and I'm leading a small team of engineers, some of whom have never used Kubernetes before. So I've found myself explaining Kubernetes to them. They seemed to find it helpful, so I thought I'd write it down and share it with the rest of you.
This article is aimed at engineers who need to deploy their code using Kubernetes, but have no idea what Kubernetes is or how it works. I'm going to tell you a story about a junior engineer. We're going to follow this engineer as they build a high-quality service, and when they run into problems, we'll see how Kubernetes can help solve them. Hopefully this will get you comfortable building your own services in k8s!
Last week in Tokio's Discord chat server someone asked a really interesting question: how can you stream a multipart body from an incoming request into an outgoing request? My struggle to answer this really helped me understand Rust async lifetimes. We'll explore why this is tricky, then design and benchmark a solution.
I learned about extensions when reading the hyper docs. But they also pop up in lots of other Rust web libraries, like http, tonic, and actix-web. So they must be really useful, if so many libraries offer them. But I personally had no idea what they were or how to use them. Today I'm going to explain what extensions really are (a set of values, keyed by type), and how you can use them to pass data between different parts of your web servers (e.g. middleware, routers, and handler functions). I'll give you a real-world example from the gRPC server I'm building at my job.
Over the last few weeks I built my own DNS client. Mostly because I thought dig (the standard DNS client) was kinda clunky. Partly because I wanted to learn more about DNS. So here's how I built it, and how you can build your own too. It's a great weekend project, and I learned a lot from finishing it.
Programming languages generally only manipulate bytes (groups of 8 bits). It can be pretty tricky to manipulate single bits. But sometimes you need to -- for example, a DNS header has some 4-bit numbers, and encodes some boolean flags into single bits. So we really need a way to parse binary data without chunking it up into bytes of 8 bits.
Luckily, Nom can do this! In the last blog post, we learned how to parse text files with Nom. The trick is to start with simple parsers that parse a few characters at a time. Then, using combinators, combine those simple parsers into more complex parsers that can deserialize an entire structured file. We can reuse this approach for parsing binary data too. Let's see how!