The “Naive” Approach
The standard-issue instinct here is: add
spring-boot-starter-web, slap@RestControlleron a class, write@GetMapping("/drivers/near/{lat}/{lon}"), and callstore.get()inside the method body. It compiles, it demos, and it is wrong in three separate ways that only surface under load.Thread pool exhaustion. Spring’s embedded Tomcat services requests from a bounded platform-thread pool — typically 200 threads by default. But a
/drivers/nearrequest is not a cheap local lookup; per Lesson 61, it’s a scatter-gather operation that fans out RPC calls to every host that owns a candidate partition and blocks waiting for responses. Each of those 200 Tomcat threads can be parked mid-request waiting on a network round-trip. At any meaningful concurrency — a few hundred simultaneous map-view refreshes — you exhaust the pool, and every subsequent request queues behind threads that are doing nothing but waiting. This is a classic thread-per-request blocking-I/O failure mode, and it is exactly the problem Java 21 virtual threads exist to solve.Silent wrong answers. A naive controller calls
store.get(key)against the local RocksDB instance only. It has no concept ofHostInfoRouter(Lesson 62) — it doesn’t know or care that the partition it needs might live on a different instance entirely. It returns whatever the local store happens to contain, which fordriverIdvalues not hashed to this instance’s partitions is simply nothing, with no error, nopartial: trueflag, nothing to indicate the response is incomplete. This is strictly worse than the honest-degradation failure modes we’ve built everywhere else in this course — it’s not a flagged partial result, it’s a confidently wrong empty result.Framework overhead hiding the physics.
DispatcherServlet, Spring’s argument resolvers, and its classloading machinery add real latency and, more importantly, obscure the fact that what you’re building is a transport adapter over an RPC protocol you already wrote by hand in Lesson 61. Wrapping that in Spring doesn’t simplify anything — it hides the one part of the system (network fan-out, timeout handling) where visibility matters most.


