Provide the following condition for the race condition for the solution proposed in the question.
- Thread A begins to execute the handler.
@work-in-progress false , so it introduces a do statement. However, before he managed to set the value of work-in-progress to true ... - Thread B begins to execute the handler.
@work-in-progress is false, so it introduces a do statement.
Now two threads do (do-the-work) at the same time. This is not what we want.
To prevent this problem, check and set the ref value in transaction dosync .
(compojure.core/GET "/myapp/internal/do-work" [] (if (dosync (when-not @work-in-progress (ref-set work-in-progress true))) (try (do-the-work) "Job completed Successfully" (finally (dosync (ref-set work-in-progress false)))) "Work in Progress please try again later"))
Another abstraction that may be useful in this scenario is atom and compare-and-set! .
(def work-in-progress (atom false)) (compojure.core/GET "/myapp/internal/do-work" [] (if (compare-and-set! work-in-progress false true) (try (do-the-work) "Job completed Successfully" (finally (reset! work-in-progress false))) "Work in Progress please try again later"))
source share