Random Core.async exercise
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
(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