added sessions for thread-safe timers

This commit is contained in:
Yann Esposito 2015-02-27 18:03:54 +01:00
parent d25a0e5589
commit f3d77f2a40
4 changed files with 93 additions and 68 deletions

View file

@ -42,20 +42,21 @@ Full example:
(defn function-called-frequently
[]
(bb/big-brother-is-watching-you) ; <-- you must start the timer
(let [session (bb/big-brother-is-watching-you)] ; <-- you must start the timer
(when (has-book?)
(read-book) ; <-- do your action
(bb/log-time :read-book) ; <-- tell the timer you've done something
(bb/log-time session :read-book) ; <-- tell the timer you've done something
(bb/log-counter :book) ; <-- increment the counter :book
)
(write-notes)
(bb/log-time :write-notes)
(bb/log-time session :write-notes)
(let [time-felt-free (feel-free)]
(bb/log-time :feel-free)
(bb/log-time session :feel-free)
(bb/log-mmetric :freetime time-felt-free))
(work-as-usual)
(bb/log-time :work-as-usual)
(bb/telescreen-off)) ; <-- end the timer loop to flush times.
(bb/log-time session :work-as-usual)
(bb/telescreen-off session) ; <-- end the timer loop to flush times.
(bb/end-session! session)) ; <-- end this session
~~~
### Init
@ -89,7 +90,7 @@ That will send data to riemann every nb-ms-metrics ms.
~~~ {.clojure}
(do
(action)
(bb/log-time :action))
(bb/log-time session :action))
~~~
Will tell big brother that the action :action finished.
@ -97,16 +98,17 @@ Generally you use timers like this:
~~~ {.clojure}
(do
(bb/big-brother-is-watching-you)
(let [session (bb/big-brother-is-watching-you)]
(action1)
(bb/log-time :action1)
(bb/log-time session :action1)
(action1)
(bb/log-time :action1)
(bb/telescreen-off))
(bb/log-time session :action1)
(bb/telescreen-off session)
(bb/end-session! session))
~~~
You declare a start time which will start the chrono.
Then each time you decalare a `log-time` it will add the time taken to the action name.
Then each time you declare a `log-time` it will add the time taken to the action name.
Once you finished your course of action you declare the timer-loop as finished.
And you stop the chrono up until the next `(bb/big-brother-is-watching-you)`.

View file

@ -21,23 +21,38 @@
(def level-by-key (atom nil))
(def n (atom 0)) ;; a number
(def session (atom 0)) ;; a simple session number
(def log-time timer/log-time)
(def log-counter counter/log-counter)
(def log-metric metrics/log-metric)
(def log-mmetric max-metrics/log-mmetric)
(defn timer-loop-finished []
(defn timer-loop-finished
([]
;; increment the number of loop
(swap! n inc)
(timer/finish-timer-loop)
(max-metrics/loop-finished)
(metrics/loop-finished)
(counter/loop-finished))
([session]
;; increment the number of loop
(swap! n inc)
(timer/finish-timer-loop session)
(max-metrics/loop-finished)
(metrics/loop-finished)
(counter/loop-finished)))
(defn end-session! [session]
(timer/end-session! session))
(defn new-session! [] (swap! session inc) @session)
;; ---- aliases
(defn big-brother-is-watching-you "Starting the timer" []
(timer/log-time :start))
(let [session (new-session!)]
(timer/log-time session :start)
session))
(def telescreen-on "Starting the timer" big-brother-is-watching-you)
(def welcome-in-miniluv "End the timer chrono" timer-loop-finished)
@ -88,7 +103,7 @@
(reset! n 0))
(defn reset-all-atoms! []
(reset! timer/times [])
(reset! timer/times {})
(reset! metrics/metrics {})
(reset! max-metrics/mmetrics {})
(reset! counter/counters {})

View file

@ -29,20 +29,18 @@
(/ (ts-timespent v)
(ts-nb v))}) st)))
;; timers atoms
(def times (atom [])) ;; timestamps
(def times (atom {})) ;; {session [timestamps]}
(def sumtimes (atom empty-sumtime)) ;; time spent by type
;; Timer
(defn- set-value! [k v] (swap! times conj [k v]))
(defn- set-value! [session k v]
(let [update-one-raw #(if (nil? %) [[k v]] (conj % [k v]))]
(swap! times #(update-in % [session] update-one-raw))))
(defn log-time
"declare the action named `k` finished"
[k]
(set-value! k (System/nanoTime)))
(defn log-time->
"declare the action named `k` finished and returned object `x`"
[x k]
(log-time k)
x)
[session k]
(set-value! session k (System/nanoTime)))
(defn- show-one-step
"get time spent during one step"
@ -70,14 +68,18 @@
[times-array]
(fmap-sumtimes #(float (/ % 1000000)) times-array))
(defn finish-timer-loop []
(defn finish-timer-loop [session]
;; Convert actual timestamps to sumtimes and aggregate them
(if (> (count @times) 1)
(let [difftime (timespent @times)
total (total-time @times)
(let [ts (get @times session)]
(if (> (count ts) 1)
(let [difftime (timespent ts)
total (total-time ts)
res (to-milliseconds (conj difftime [:total [total 1]]))]
(swap! sumtimes add-sumtimes res)))
(reset! times []))
(swap! sumtimes add-sumtimes res))))
(swap! times assoc session []))
(defn end-session! [session]
(swap! times dissoc session))
(defn reset-acc! []
(reset! sumtimes empty-sumtime))

View file

@ -11,21 +11,22 @@
(do
(reset-all-atoms!)
;; first loop
(telescreen-on)
(Thread/sleep 30)
(log-time :x1)
(Thread/sleep 30)
(log-time :x2)
(Thread/sleep 30)
(log-time :end)
(telescreen-off)
(let [session (telescreen-on)]
(Thread/sleep session 30)
(log-time session :x1)
(Thread/sleep session 30)
(log-time session :x2)
(Thread/sleep session 30)
(log-time session :end)
(telescreen-off session)
;; second loop
(log-time :start)
(log-time session :start)
(Thread/sleep 30)
(log-time :x2)
(log-time session :x2)
(Thread/sleep 30)
(log-time :end)
(telescreen-off)
(log-time session :end)
(telescreen-off session)
(end-session! session))
(let [result (resume-map 1000)]
(is (contains? result :nb))
(is (contains? result :x1))
@ -100,9 +101,12 @@
(gen/vector gen/keyword))]
(do
(reset-all-atoms!)
(doall (map (fn [a] (do (log-time a) (Thread/sleep 10)))
(let [session (telescreen-on)]
(doall (map (fn [a] (do (log-time session a) (Thread/sleep 10)))
actions))
(timer-loop-finished))
(timer-loop-finished session)
(end-session! session)))
(let [result (resume-map 1000)]
(every? #(contains? result %) (rest actions)))))
@ -113,8 +117,10 @@
(gen/vector gen/keyword))]
(do
(reset-all-atoms!)
(doall (map (fn [a] (do (log-time a) (Thread/sleep 10)))
(let [session (telescreen-on)]
(doall (map (fn [a] (do (log-time session a) (Thread/sleep 10)))
actions))
(timer-loop-finished))
(timer-loop-finished session)
(end-session! session)))
(let [result (resume-map 1000)]
(every? #(>= (:total result) (get result %)) (rest actions)))))