added sessions for thread-safe timers
This commit is contained in:
parent
d25a0e5589
commit
f3d77f2a40
4 changed files with 93 additions and 68 deletions
26
README.md
26
README.md
|
@ -42,20 +42,21 @@ Full example:
|
||||||
|
|
||||||
(defn function-called-frequently
|
(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?)
|
(when (has-book?)
|
||||||
(read-book) ; <-- do your action
|
(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
|
(bb/log-counter :book) ; <-- increment the counter :book
|
||||||
)
|
)
|
||||||
(write-notes)
|
(write-notes)
|
||||||
(bb/log-time :write-notes)
|
(bb/log-time session :write-notes)
|
||||||
(let [time-felt-free (feel-free)]
|
(let [time-felt-free (feel-free)]
|
||||||
(bb/log-time :feel-free)
|
(bb/log-time session :feel-free)
|
||||||
(bb/log-mmetric :freetime time-felt-free))
|
(bb/log-mmetric :freetime time-felt-free))
|
||||||
(work-as-usual)
|
(work-as-usual)
|
||||||
(bb/log-time :work-as-usual)
|
(bb/log-time session :work-as-usual)
|
||||||
(bb/telescreen-off)) ; <-- end the timer loop to flush times.
|
(bb/telescreen-off session) ; <-- end the timer loop to flush times.
|
||||||
|
(bb/end-session! session)) ; <-- end this session
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
### Init
|
### Init
|
||||||
|
@ -89,7 +90,7 @@ That will send data to riemann every nb-ms-metrics ms.
|
||||||
~~~ {.clojure}
|
~~~ {.clojure}
|
||||||
(do
|
(do
|
||||||
(action)
|
(action)
|
||||||
(bb/log-time :action))
|
(bb/log-time session :action))
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
Will tell big brother that the action :action finished.
|
Will tell big brother that the action :action finished.
|
||||||
|
@ -97,16 +98,17 @@ Generally you use timers like this:
|
||||||
|
|
||||||
~~~ {.clojure}
|
~~~ {.clojure}
|
||||||
(do
|
(do
|
||||||
(bb/big-brother-is-watching-you)
|
(let [session (bb/big-brother-is-watching-you)]
|
||||||
(action1)
|
(action1)
|
||||||
(bb/log-time :action1)
|
(bb/log-time session :action1)
|
||||||
(action1)
|
(action1)
|
||||||
(bb/log-time :action1)
|
(bb/log-time session :action1)
|
||||||
(bb/telescreen-off))
|
(bb/telescreen-off session)
|
||||||
|
(bb/end-session! session))
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
You declare a start time which will start the chrono.
|
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.
|
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)`.
|
And you stop the chrono up until the next `(bb/big-brother-is-watching-you)`.
|
||||||
|
|
|
@ -21,23 +21,38 @@
|
||||||
(def level-by-key (atom nil))
|
(def level-by-key (atom nil))
|
||||||
|
|
||||||
(def n (atom 0)) ;; a number
|
(def n (atom 0)) ;; a number
|
||||||
|
(def session (atom 0)) ;; a simple session number
|
||||||
|
|
||||||
(def log-time timer/log-time)
|
(def log-time timer/log-time)
|
||||||
(def log-counter counter/log-counter)
|
(def log-counter counter/log-counter)
|
||||||
(def log-metric metrics/log-metric)
|
(def log-metric metrics/log-metric)
|
||||||
(def log-mmetric max-metrics/log-mmetric)
|
(def log-mmetric max-metrics/log-mmetric)
|
||||||
|
|
||||||
(defn timer-loop-finished []
|
(defn timer-loop-finished
|
||||||
|
([]
|
||||||
;; increment the number of loop
|
;; increment the number of loop
|
||||||
(swap! n inc)
|
(swap! n inc)
|
||||||
(timer/finish-timer-loop)
|
|
||||||
(max-metrics/loop-finished)
|
(max-metrics/loop-finished)
|
||||||
(metrics/loop-finished)
|
(metrics/loop-finished)
|
||||||
(counter/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
|
;; ---- aliases
|
||||||
(defn big-brother-is-watching-you "Starting the timer" []
|
(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 telescreen-on "Starting the timer" big-brother-is-watching-you)
|
||||||
|
|
||||||
(def welcome-in-miniluv "End the timer chrono" timer-loop-finished)
|
(def welcome-in-miniluv "End the timer chrono" timer-loop-finished)
|
||||||
|
@ -88,7 +103,7 @@
|
||||||
(reset! n 0))
|
(reset! n 0))
|
||||||
|
|
||||||
(defn reset-all-atoms! []
|
(defn reset-all-atoms! []
|
||||||
(reset! timer/times [])
|
(reset! timer/times {})
|
||||||
(reset! metrics/metrics {})
|
(reset! metrics/metrics {})
|
||||||
(reset! max-metrics/mmetrics {})
|
(reset! max-metrics/mmetrics {})
|
||||||
(reset! counter/counters {})
|
(reset! counter/counters {})
|
||||||
|
|
|
@ -29,20 +29,18 @@
|
||||||
(/ (ts-timespent v)
|
(/ (ts-timespent v)
|
||||||
(ts-nb v))}) st)))
|
(ts-nb v))}) st)))
|
||||||
;; timers atoms
|
;; timers atoms
|
||||||
(def times (atom [])) ;; timestamps
|
(def times (atom {})) ;; {session [timestamps]}
|
||||||
(def sumtimes (atom empty-sumtime)) ;; time spent by type
|
(def sumtimes (atom empty-sumtime)) ;; time spent by type
|
||||||
|
|
||||||
;; Timer
|
;; 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
|
(defn log-time
|
||||||
"declare the action named `k` finished"
|
"declare the action named `k` finished"
|
||||||
[k]
|
[session k]
|
||||||
(set-value! k (System/nanoTime)))
|
(set-value! session k (System/nanoTime)))
|
||||||
(defn log-time->
|
|
||||||
"declare the action named `k` finished and returned object `x`"
|
|
||||||
[x k]
|
|
||||||
(log-time k)
|
|
||||||
x)
|
|
||||||
|
|
||||||
(defn- show-one-step
|
(defn- show-one-step
|
||||||
"get time spent during one step"
|
"get time spent during one step"
|
||||||
|
@ -70,14 +68,18 @@
|
||||||
[times-array]
|
[times-array]
|
||||||
(fmap-sumtimes #(float (/ % 1000000)) 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
|
;; Convert actual timestamps to sumtimes and aggregate them
|
||||||
(if (> (count @times) 1)
|
(let [ts (get @times session)]
|
||||||
(let [difftime (timespent @times)
|
(if (> (count ts) 1)
|
||||||
total (total-time @times)
|
(let [difftime (timespent ts)
|
||||||
|
total (total-time ts)
|
||||||
res (to-milliseconds (conj difftime [:total [total 1]]))]
|
res (to-milliseconds (conj difftime [:total [total 1]]))]
|
||||||
(swap! sumtimes add-sumtimes res)))
|
(swap! sumtimes add-sumtimes res))))
|
||||||
(reset! times []))
|
(swap! times assoc session []))
|
||||||
|
|
||||||
|
(defn end-session! [session]
|
||||||
|
(swap! times dissoc session))
|
||||||
|
|
||||||
(defn reset-acc! []
|
(defn reset-acc! []
|
||||||
(reset! sumtimes empty-sumtime))
|
(reset! sumtimes empty-sumtime))
|
||||||
|
|
|
@ -11,21 +11,22 @@
|
||||||
(do
|
(do
|
||||||
(reset-all-atoms!)
|
(reset-all-atoms!)
|
||||||
;; first loop
|
;; first loop
|
||||||
(telescreen-on)
|
(let [session (telescreen-on)]
|
||||||
(Thread/sleep 30)
|
(Thread/sleep session 30)
|
||||||
(log-time :x1)
|
(log-time session :x1)
|
||||||
(Thread/sleep 30)
|
(Thread/sleep session 30)
|
||||||
(log-time :x2)
|
(log-time session :x2)
|
||||||
(Thread/sleep 30)
|
(Thread/sleep session 30)
|
||||||
(log-time :end)
|
(log-time session :end)
|
||||||
(telescreen-off)
|
(telescreen-off session)
|
||||||
;; second loop
|
;; second loop
|
||||||
(log-time :start)
|
(log-time session :start)
|
||||||
(Thread/sleep 30)
|
(Thread/sleep 30)
|
||||||
(log-time :x2)
|
(log-time session :x2)
|
||||||
(Thread/sleep 30)
|
(Thread/sleep 30)
|
||||||
(log-time :end)
|
(log-time session :end)
|
||||||
(telescreen-off)
|
(telescreen-off session)
|
||||||
|
(end-session! session))
|
||||||
(let [result (resume-map 1000)]
|
(let [result (resume-map 1000)]
|
||||||
(is (contains? result :nb))
|
(is (contains? result :nb))
|
||||||
(is (contains? result :x1))
|
(is (contains? result :x1))
|
||||||
|
@ -100,9 +101,12 @@
|
||||||
(gen/vector gen/keyword))]
|
(gen/vector gen/keyword))]
|
||||||
(do
|
(do
|
||||||
(reset-all-atoms!)
|
(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))
|
actions))
|
||||||
(timer-loop-finished))
|
(timer-loop-finished session)
|
||||||
|
(end-session! session)))
|
||||||
(let [result (resume-map 1000)]
|
(let [result (resume-map 1000)]
|
||||||
(every? #(contains? result %) (rest actions)))))
|
(every? #(contains? result %) (rest actions)))))
|
||||||
|
|
||||||
|
@ -113,8 +117,10 @@
|
||||||
(gen/vector gen/keyword))]
|
(gen/vector gen/keyword))]
|
||||||
(do
|
(do
|
||||||
(reset-all-atoms!)
|
(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))
|
actions))
|
||||||
(timer-loop-finished))
|
(timer-loop-finished session)
|
||||||
|
(end-session! session)))
|
||||||
(let [result (resume-map 1000)]
|
(let [result (resume-map 1000)]
|
||||||
(every? #(>= (:total result) (get result %)) (rest actions)))))
|
(every? #(>= (:total result) (get result %)) (rest actions)))))
|
||||||
|
|
Loading…
Reference in a new issue