Archive
1290 posts · Page 97 of 108. ← Blog
Most languages treat testing as an afterthought — a separate framework you bolt on, a separate directory, a separate mental mode. Rust treats it as a first-class, built-in feature: testing is part of the language and its tooling, you write tests right next to the code they test, and `cargo test` just works. This tight integration, combined with Rust's culture of correctness, makes testing in Rust unusually pleasant and encourages a habit that pairs perfectly with the compiler's guarantees.
Most languages treat testing as an afterthought. Rust treats it as first-class and built-in: testing is part of the language and tooling, you write tests right next to the code, and cargo test just works. This tight integration makes testing in Rust unusually pleasant.
How a real shell tool lets the model run commands, and an environment provider tells it which shell it is driving.
Pair a run_shell tool with an EnvironmentProvider that probes the shell once and injects OS-correct idioms, contrasting stateless and persistent shell modes.
Notes from contributing to Google's open-source Spanner Migration Tool (HarbourBridge). Where to start reading the codebase, where the load-bearing logic lives, and the parts that look simple but aren't.
Threads are great for CPU-bound parallelism, but for handling thousands of network connections — each mostly waiting — spawning a thread per connection doesn't scale (recall the C10K problem from the OS series). Async/await is Rust's answer: write code that looks sequential but doesn't block a thread while waiting, letting a handful of threads handle enormous concurrency. Rust's async is powerful and zero-cost, with one distinctive twist — you bring your own runtime to actually run the async code.
For handling thousands of connections each mostly waiting, spawning a thread per connection doesn't scale. Async/await is Rust's answer: write code that looks sequential but doesn't block a thread while waiting. Rust's async is powerful and zero-cost, with one distinctive twist — you bring your own runtime.
How to keep a long-running conversation inside the context window by chaining compaction strategies from gentle to aggressive.
Chain four compaction strategies from tool-result collapse to summarization to sliding window to truncation, each gated by a trigger and a preservation floor.
Spanner partitions by primary-key range. A monotonically-increasing PK like a timestamp or UUID-v1 funnels all writes to one server. The fix changes everything from your sequence strategy to your tenant model.
There are two great philosophies of concurrency: share memory (with locks, as the previous posts covered) or share nothing and communicate by passing messages. The message-passing school has a famous slogan — "do not communicate by sharing memory; instead, share memory by communicating" — and Rust supports it fully with channels. Instead of multiple threads carefully locking shared state, ownership of data is transferred from one thread to another through a channel, and Rust's ownership system makes that transfer clean and safe.
There are two great philosophies of concurrency: share memory (with locks) or share nothing and communicate by passing messages. Rust supports channels fully — and its ownership system makes message passing especially natural, because sending data through a channel is transferring ownership.
How a ContextProvider injects extra messages and tools into every run — a live todo list and calendar — with state that survives serialize and resume.
A ContextProvider injects a live todo list and calendar into each run and contributes session-mutating tools, with state that serializes to JSON and resumes.
Interleaving a child table into its parent co-locates the rows for fast joins. It also tightens coupling in ways that bite you on the next schema migration. A practitioner's decision matrix.
How does the Rust compiler actually know that an `Arc<Mutex<T>>` is safe to share across threads but an `Rc<T>` isn't? The answer is two of the most elegant ideas in Rust: a pair of marker traits, `Send` and `Sync`, that encode thread-safety directly into the type system. They're rarely written by hand and often invisible, yet they're the machinery that makes fearless concurrency work — the compiler reasons about thread-safety by checking these traits, automatically, at compile time.
How does the compiler know an Arc<Mutex<T>> is safe to share across threads but an Rc<T> isn't? The answer is two elegant marker traits — Send and Sync — that encode thread-safety directly into the type system. Rarely written by hand and often invisible, they're the machinery that makes fearless concurrency work.
How wrapping one agent as a tool.Tool lets an orchestrator agent delegate to a specialist — composition all the way down, with no routing code.
Wrap a specialist agent with agenttool.New so an orchestrator calls it like any tool, cascading two levels deep from orchestrator to weather agent to leaf function.
A bulk migration takes hours; the application can't be offline that long. CDC keeps the source and destination in sync while the bulk runs, and a quick cutover swaps traffic. The handoff between bulk and CDC is where most migrations go wrong.