Question

This is presented as a solution to the sleeping barber problem. (Attributed to CGrand, but I found the reference here)

yanked from cgrand

I'm curious about the dosync block in enter-the-shop. My understanding is that this is a transaction, and so empty-seats will remain consistent because of STM. However, isn't there the possibility of send-off being called multiple times if the transaction gets retried? If not, why, and if so, how would one resolve it?

UPDATE

While the accepted answer is still correct, one thing I just noticed is there's an optimization that could be made--there's no reason to call send-off inside the transaction. It can be sent afterwards once you have the return value of the transaction, as follows:

(if (dosync
       (when (pos? @empty-seats)
         (alter empty-seats dec)))
    (send-off barber cut-hair n)
    (debug "(s) turning away customer" n))

Interestingly I figured this out while working on the Haskell equivalent, which forces you to use different types for "agents" inside STM and outside STM. The original solution above wouldn't compile, as they had to be either both in a transaction or both outside any transaction. (My first reaction was to put them both inside the transaction, until I realized there was no need for this and they could both be extracted).

I think the modified transaction should be superior in that it closes the transaction faster, removes a variable from the transaction, and I think is easier to read (there's no need to even wonder about the possibility of it being sent twice--which actually makes this whole question moot) Still, I'll leave the question up anyway for anyone else who needs to know about how STM and agents interact.

Was it helpful?

Solution

Quoting the clojure.org page on agents:

Agents are integrated with the STM - any dispatches made in a transaction are held until it commits, and are discarded if it is retried or aborted.

So the send-off will only get run once, when(/if) the STM transaction is successfully committed.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top