Logo
Logo
20 results for
  • Here’s an uncomfortable truth about async file I/O: on most operating systems, it doesn’t really exist. When you call tokio::fs::read_to_string, Tokio dispatches the operation to a thread pool because Linux’s file I/O isn’t truly asynchronous (yes, there’s io_uring, but Tokio doesn’t use it by default). Network I/O, on the other hand, is genuinely async through epoll/kqueue.

    Understanding this distinction matters. It changes how you architect things.

    The Async I/O Traits

    Tokio defines two core traits that mirror their std counterparts:

    Rust tutorial rust async tokio Created Tue, 28 Jan 2025 08:55:13 +0000
  • Debugging a microservices system with only logs is like debugging a multi-threaded program with only print statements — possible, but painful in ways that are entirely avoidable. The first time I had to trace a slow request through six services using log grep, I understood why distributed tracing exists. An hour of log correlation that should have been a 10-second click on a flame chart. Distributed tracing gives you that flame chart.

    Go tutorial golang microservices Created Tue, 28 Jan 2025 00:00:00 +0000
  • Every production outage I’ve investigated boils down to one of two things: unbounded retries or missing timeouts. A function that “usually takes 50ms” eventually takes 30 seconds because the database is overloaded, and suddenly your entire service is frozen because every thread is waiting on that one slow call.

    Timeouts aren’t optional in production code. They’re as important as error handling. And graceful shutdown — cleanly stopping your service when it’s time to deploy — is what separates “my service runs in production” from “my service runs in production well.”

    Rust tutorial rust async tokio Created Sun, 26 Jan 2025 12:24:51 +0000
  • I used to believe that eventual consistency was an exotic property of distributed databases that I’d only encounter at Google scale. Then I added a Redis cache to a simple CRUD service and immediately had a bug where users couldn’t see their own updates. Welcome to eventual consistency — it shows up the moment you have two places that store the same data.

    Eventual consistency means that if you stop writing to a system, all replicas will eventually converge to the same value. The word “eventually” can mean milliseconds or minutes, depending on the system. The hard part isn’t the definition — it’s designing application code that works correctly even when replicas haven’t converged yet.

    Go tutorial golang networking Created Sat, 25 Jan 2025 00:00:00 +0000
  • This is the lesson I wish someone had shoved in my face before I wrote my first select! loop. I lost three days to a bug where messages were disappearing from a queue. No errors. No panics. Just… gone. Turns out, select! was cancelling a future that had already read the message from the channel but hadn’t finished processing it.

    Cancellation safety is the most under-discussed footgun in async Rust. If you use select!, you need to understand this.

    Rust tutorial rust async tokio Created Fri, 24 Jan 2025 09:41:22 +0000
  • I once crashed a third-party API by spawning 10,000 concurrent requests from an async Rust service. The code was correct — every request completed (eventually). But the API’s rate limiter kicked in after 50 concurrent connections, and we got IP-banned for two hours.

    The fix was a single type: tokio::sync::Semaphore. Five lines of code turned “as fast as possible” into “at most N at a time.”

    What’s a Semaphore?

    A semaphore is a counter with a maximum value. You acquire a permit before doing work, and release it when you’re done. If all permits are taken, acquiring blocks (yields) until one becomes available.

    Rust tutorial rust async tokio Created Wed, 22 Jan 2025 15:08:36 +0000
  • Go’s os and path/filepath packages are among the most underappreciated in the standard library. Most developers know os.Open, os.Create, and os.ReadFile. Far fewer know os.MkdirAll, os.CreateTemp, filepath.WalkDir, or the difference between path and path/filepath — which is the difference between code that works everywhere and code that silently breaks on Windows.

    I maintain a CLI tool that runs on macOS, Linux, and Windows. The file operation bugs I’ve shipped have taught me exactly which parts of these packages require care.

    Go tutorial golang stdlib Created Wed, 22 Jan 2025 00:00:00 +0000
  • “Should I use tokio::sync::Mutex or std::sync::Mutex in async code?” I’ve seen this question in every Rust Discord server, every forum, every team Slack. And the answer most people give — “always use the async one in async code” — is wrong.

    The real answer depends on how long you hold the lock and whether you need to .await while holding it. Get this wrong and you’ll either deadlock your runtime or tank your performance.

    Rust tutorial rust async tokio Created Mon, 20 Jan 2025 07:15:44 +0000
  • A test suite that passes without -race is not a clean bill of health. It’s a test suite that hasn’t checked one of the most insidious categories of bugs in Go: data races. I’ve shipped code that passed every test, passed code review, and then caused memory corruption in production because two goroutines were reading and writing a map concurrently. The race detector would have found it in under a second. We just never ran it.

    Go tutorial golang testing Created Mon, 20 Jan 2025 00:00:00 +0000
  • The first real async service I built had a classic architecture: an HTTP handler receives a request, puts work on a queue, a background worker processes it, and the result gets sent back. In Go, this is channels all day. In async Rust, it’s also channels — but you’ve got four different kinds to choose from, and picking the wrong one leads to subtle bugs.

    This lesson covers all four of Tokio’s channel types and when to reach for each one.

    Rust tutorial rust async tokio Created Sat, 18 Jan 2025 13:52:28 +0000