Created
September 17, 2009 10:31
-
-
Save cgrand/188441 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defn walk-out [customer] | |
(ref-set customer :outside)) | |
(defn wait [customer {q :queue}] | |
(alter q conj customer) | |
(ref-set customer :waiting)) | |
(defn sleeping? [barber] | |
(= :sleeping (ensure barber))) | |
(defn wake-up [barber] | |
(ref-set barber :awake)) | |
(defn full? [{q :queue, max :max}] | |
(<= max (count (ensure q)))) | |
(defn next-customer [{q :queue}] | |
(when-let [customer (peek (ensure q))] | |
(alter q pop) | |
customer)) | |
(defn do-later [f] | |
(future | |
(Thread/sleep (+ 100 (rand-int 600))) | |
(dosync (f)))) | |
(defn walk-in [shop customer] | |
(if (full? shop) | |
(do-later #(walk-in shop customer)) | |
(let [barber (shop :barber)] | |
(when (sleeping? barber) | |
(wake-up barber)) | |
(wait customer shop)))) | |
(defn cut-hair-or-sleep [shop] | |
(if-let [customer (next-customer shop)] | |
(do | |
(ref-set (shop :barber) {:cutting-hair customer}) | |
(ref-set customer :serviced) | |
(do-later | |
#(do | |
(ref-set customer :new-haircut) | |
(cut-hair-or-sleep shop)))) | |
(ref-set (shop :barber) :sleeping))) | |
(defn add-log [ref s] | |
(add-watch ref :log | |
#(println s %4))) | |
(defn shop [n] | |
(let [shop {:barber (ref :sleeping) | |
:queue (ref clojure.lang.PersistentQueue/EMPTY) | |
:max n}] | |
(doto (shop :barber) | |
(add-log "barber") | |
(add-watch :react | |
(fn [_ _ _ state] | |
(when (= state :awake) | |
(dosync (cut-hair-or-sleep shop)))))) | |
shop)) | |
(defn customer [id] | |
(-> (ref :outside) | |
(add-log (str "customer " id)))) | |
(let [shop (shop 3)] | |
(doseq [i (range 20)] | |
(future (dosync (walk-in shop (customer i)))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment