Async
Why a passing test proves nothing
Concurrency is the one area where running the code a thousand times tells you almost nothing. What to do instead.
8 minutes · interleaving · model checking · decision points
The bug that only happens on the fourteenth Tuesday
A concurrency bug is a bug in the *order* things happened, and order is the one thing a test suite does not control. Running a concurrent program is sampling: you get one interleaving out of an enormous number, chosen by a scheduler that is trying to be fast rather than trying to be thorough. Passing a thousand times means a thousand samples came back clean. It does not mean the bad one is not there. It usually means the machine was not busy enough for it that afternoon.
This is why most people's working model of concurrency is a collection of superstitions. You add a lock, it stops happening, and you file that away as knowledge. What you actually learned was that a lock changed the timing enough that a thousand more samples came back clean too.
Everything in this app exists to replace sampling with enumeration. The engine does not run your program once. It walks the space of interleavings, and when it finds one that breaks your assertion, it hands you that exact schedule to step through — forwards and backwards, as many times as you like.