diff --git a/README.md b/README.md index e49a6c9..2889f36 100644 --- a/README.md +++ b/README.md @@ -42,20 +42,21 @@ Full example: (defn function-called-frequently [] - (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-counter :book) ; <-- increment the counter :book - ) - (write-notes) - (bb/log-time :write-notes) - (let [time-felt-free (feel-free)] - (bb/log-time :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. + (let [session (bb/big-brother-is-watching-you)] ; <-- you must start the timer + (when (has-book?) + (read-book) ; <-- do your action + (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 session :write-notes) + (let [time-felt-free (feel-free)] + (bb/log-time session :feel-free) + (bb/log-mmetric :freetime time-felt-free)) + (work-as-usual) + (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) - (action1) - (bb/log-time :action1) - (action1) - (bb/log-time :action1) - (bb/telescreen-off)) + (let [session (bb/big-brother-is-watching-you)] + (action1) + (bb/log-time session :action1) + (action1) + (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)`. diff --git a/src/bigbrother/core.clj b/src/bigbrother/core.clj index 36d46c3..65cf428 100644 --- a/src/bigbrother/core.clj +++ b/src/bigbrother/core.clj @@ -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 [] - ;; increment the number of loop - (swap! n inc) - (timer/finish-timer-loop) - (max-metrics/loop-finished) - (metrics/loop-finished) - (counter/loop-finished)) +(defn timer-loop-finished + ([] + ;; increment the number of loop + (swap! n inc) + (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 {}) diff --git a/src/bigbrother/timer.clj b/src/bigbrother/timer.clj index dbdcf43..96de066 100644 --- a/src/bigbrother/timer.clj +++ b/src/bigbrother/timer.clj @@ -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) - res (to-milliseconds (conj difftime [:total [total 1]]))] - (swap! sumtimes add-sumtimes res))) - (reset! 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)))) + (swap! times assoc session [])) + +(defn end-session! [session] + (swap! times dissoc session)) (defn reset-acc! [] (reset! sumtimes empty-sumtime)) diff --git a/test/bigbrother/core_test.clj b/test/bigbrother/core_test.clj index 22d7fc4..980c071 100644 --- a/test/bigbrother/core_test.clj +++ b/test/bigbrother/core_test.clj @@ -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) - ;; second loop - (log-time :start) - (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 session :start) + (Thread/sleep 30) + (log-time session :x2) + (Thread/sleep 30) + (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))) - actions)) - (timer-loop-finished)) + (let [session (telescreen-on)] + + (doall (map (fn [a] (do (log-time session a) (Thread/sleep 10))) + actions)) + (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))) - actions)) - (timer-loop-finished)) + (let [session (telescreen-on)] + (doall (map (fn [a] (do (log-time session a) (Thread/sleep 10))) + actions)) + (timer-loop-finished session) + (end-session! session))) (let [result (resume-map 1000)] (every? #(>= (:total result) (get result %)) (rest actions)))))