-
Notifications
You must be signed in to change notification settings - Fork 0
/
listeners.clj
55 lines (50 loc) · 2.04 KB
/
listeners.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
(ns monkey.ci.listeners
(:require [clojure.core.async :as ca]
[clojure.tools.logging :as log]
[monkey.ci.storage :as st]))
(defn- update-job [rt evt f & args]
(apply st/patch-build-results
(:storage rt)
(:sid evt)
update-in [:jobs (:id evt)] f args))
(defn job-started [rt evt]
(update-job rt evt merge (-> evt
(select-keys [:id :dependencies :labels])
(assoc :start-time (:time evt)))))
(defn job-completed [rt evt]
(update-job rt evt merge {:end-time (:time evt)
:status (:status evt)}))
(defn save-build-result
"Handles a `build/completed` event to store the result."
[rt evt]
(let [r (select-keys evt [:exit :result])]
(log/debug "Saving build result:" r)
(st/patch-build-results (:storage rt)
(get-in evt [:build :sid])
merge r)))
(defn build-update-handler
"Handles a build update event. Because many events may come in close proximity,
we need to queue them to avoid losing data."
[rt]
(let [handlers {:job/start job-started
:job/end job-completed
:build/completed save-build-result}
ch (ca/chan 10)
dispatch-sub (fn [s dest]
(ca/go-loop [v (ca/<! s)]
(when v
(log/debug "Handling:" v)
(try
(dest rt v)
(catch Exception ex
;; TODO Handle this better
(log/error "Unable to handle event" ex)))
(recur (ca/<! s)))))]
;; Naive implementation: process them in sequence. This does not look
;; to the sid for optimization, so it could be faster.
(dispatch-sub ch (fn [rt evt]
(when-let [h (get handlers (:type evt))]
(h rt evt))))
(fn [evt]
(ca/put! ch evt)
nil)))