concurrency
Concurrent fan-out: errgroup vs JoinSet
Each warehouse query sleeps a per-warehouse latency_ms to simulate a remote call. Sum of latencies = 400 ms; max = 150 ms. Both backends complete in ~150 ms — the test asserts < 400 ms to catch any regression to serial execution.
// shop-two-backends not found at build time // shop-two-backends not found at build time What to take away
Go uses errgroup.WithContext. Each
goroutine writes to its own pre-allocated results[i]
slot — no shared mutation, no mutex. The buggy version (mutating a
shared map without a lock) compiles cleanly in Go and fails only
under go test -race or in production.
Rust uses tokio::task::JoinSet with
each spawned task taking move ownership of its
Warehouse. The borrow checker would refuse the
shared-mutation bug at compile time. Tasks complete in arbitrary
order, so the response is sorted by warehouse.id
post-hoc for stable output.
The headline: in Go, the safety of your concurrent code is something you (and your reviewer) verify. In Rust, it's something the compiler refuses to let you ship without.