Introducing safe side effects into the STM
The STM isn't safe as far as side effects are concerned. Since a dosync
block may get retried, possibly more than once, any side effects will be executed again and again, whether they should be or not. Values may get written to the screen or logfile multiple times. Worse, values may be written to the database more than once.
However, all programs must produce side effects. The trick is adding them while getting a handle on complexity. The easiest way to do that is to keep side effects out of transactions.
For this recipe, to illustrate what can happen, we'll simulate thread starvation. That sounds serious, but it just means that one thread isn't able to access the resources it needs, so it can't do its job. We'll also use an atom (a reference that isn't controlled by the STM) to keep track of the number of times the STM retries a call to an agent. That way, we can see what happens that creates the problem, and what we need to do to fix it.