Concurrency
7 engineering logs on Concurrency. Newest first.
- Immutability is a concurrency strategy, not a style preference
Why a shared mutable object is a lock you forgot to take, why defensive copying is the tax you pay for not deciding, and why the allocation cost is smaller than the synchronisation it removes.
- Thread pool starvation from nested async calls
Why a task that waits on another task in the same pool deadlocks with no error, why the common ForkJoinPool makes this a shared fate across libraries, and why the fix is separate pools rather than bigger ones.
- Optimistic vs pessimistic locking: choose by contention, not preference
Why a version column outperforms row locks until it does not, why the crossover point is measurable rather than a matter of taste, and why retrying an optimistic failure without thinking is how you lose a customer's edit.
- The GIL is not why your Python is slow
Why the interpreter lock is released during almost everything a web service does, what the profile actually says when a service is slow, and the narrow case where the GIL is genuinely the bottleneck.
- Async does not mean parallel, and confusing them costs you a thread pool
Why an event loop with one thread can serve ten thousand connections and still be destroyed by one CPU bound handler, and why marking a method async does nothing for work that never waits.
- Deadlocks are a lock ordering bug, and lock ordering is a design decision
Why two transactions doing the same thing in a different order will eventually stop forever, why the database picking a victim is the good outcome, and why sorting your identifiers before you touch them removes an entire class of incident.
- Decoding isolation levels: I built a toy DB to force dirty reads and phantom reads
Why the ANSI isolation table does not describe your database, what a phantom read actually is at the index level, and why snapshot isolation still lets two correct transactions corrupt each other.