Skip to content

Instantly share code, notes, and snippets.

@Deraen
Created May 7, 2014 21:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Deraen/a46ebc7dea993d90febe to your computer and use it in GitHub Desktop.
Save Deraen/a46ebc7dea993d90febe to your computer and use it in GitHub Desktop.
Random Core.async exercise
(ns foobar.core
(:require [clojure.core.async :as async :refer [chan go timeout >! alts! alts!! <! <!! close!]]))
(defn -main []
(let [running (atom true)
num-cars 20
ferry-queue (chan)
ferry (chan)
intersection (chan)
msgs (chan)
ready (chan)]
(go (while @running
(println (<! msgs))))
;; Traffic lights - simple, only one car permited inside intersection at once
(go (while @running
(let [[num reply] (<! intersection)]
(>! msgs (str "Auto " num ", risteysalueella"))
(<! (timeout (rand-int 200)))
(>! msgs (str "Auto " num ", poistui liikennevaloista"))
(>! reply true))))
;; Ferry
(go (loop [queue []]
(let [[num reply :as car] (<! ferry-queue)]
(if (= num -1)
;; [-1] is special message which tells that ferry arrived at platform
(do
(>! ferry queue)
(recur []))
(recur (conj queue car))
))))
(go (while @running
(>! msgs (str "Lautta saapuu L"))
;; Ask for ferry-queue
(>! ferry-queue [-1])
;; Wait for queue response
(let [cars (<! ferry)]
(doseq [[num _] cars]
(>! msgs (str "Auto " num ", nousee lautalle")))
;; L -> D
(<! (timeout (rand-int 400)))
(>! msgs (str "Lautta saapuu D"))
(doseq [[_ reply] cars]
(>! reply true))
;; D -> L
(<! (timeout (rand-int 400)))
)))
;; Cars
(doseq [i (range num-cars)]
(let [from (rand-nth [:a :b])
to (rand-nth [:c :d])
car-ch (chan)]
(go
(>! msgs (str "Auto luotu " i ", reitti " from "->" to))
;; From A / B - Intersection
(<! (timeout (rand-int 100)))
(>! msgs (str "Auto " i ", saapui liikennevaloihin"))
(>! intersection [i car-ch])
(<! car-ch)
;; From intersection to Ferry or C
(<! (timeout (rand-int 100)))
(when (= to :d)
(>! msgs (str "Auto " i ", jonottaa lautalle"))
(>! ferry-queue [i car-ch])
(<! car-ch)
;; From ferry to D
(<! (timeout (rand-int 100))))
(>! msgs (str "Auto " i ", poistuu " to))
(>! ready i))
(Thread/sleep (rand-int 100))))
;; Block until finished
(loop [ready-cars []]
;; (println "ready " (count ready-cars) " / " num-cars)
(if (< (count ready-cars) num-cars)
(recur (conj ready-cars (<!! ready)))))
;; Stop threads
(reset! running false)
))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment