forked from riemann/riemann
-
Notifications
You must be signed in to change notification settings - Fork 0
/
controlled.clj
71 lines (61 loc) · 1.86 KB
/
controlled.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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
(ns riemann.time.controlled
"Provides controllable periodic and deferred execution. Calling (advance!
delta-in-seconds) moves the clock forward, triggering events that would have
occurred, in sequence."
(:refer-clojure :exclude [abs])
(:require [riemann.time :refer :all]
[clojure.math.numeric-tower :refer :all]))
(def clock
"Reference to the current time, in seconds."
(atom nil))
(defn reset-clock!
[]
(reset! clock 0))
(defn reset-time!
"Resets the clock and task queue. If a function is given, calls f after
resetting the time and task list."
([f] (reset-time!) (f))
([]
(reset-clock!)
(reset-tasks!)))
(defn set-time!
"Sets the current time, without triggering callbacks."
[t]
(reset! clock t))
(defn unix-time-controlled
[]
@clock)
(defn linear-time-controlled
[]
@clock)
(defn advance!
"Advances the clock to t seconds, triggering side effects."
[t]
(when (< @clock t)
(loop []
(when-let [task (poll-task!)]
(if (<= (:t task) t)
(do
; Consume task
(swap! clock max (:t task))
(run task)
(when-let [task' (succ task)]
(schedule-sneaky! task'))
(recur))
; Return task
(schedule-sneaky! task))))
(swap! clock max t)))
(defmacro with-controlled-time!
"Like control-time! but for without the fn callback. Again, *not* threadsafe;
bindings take effect globally."
[& body]
; Please forgive me
`(with-redefs [riemann.time/unix-time unix-time-controlled
riemann.time/linear-time linear-time-controlled]
~@body))
(defn control-time!
"Switches riemann.time functions to time.controlled counterparts, invokes f,
then restores them. Definitely not threadsafe. Not safe by any standard,
come to think of it. Only for testing purposes."
[f]
(with-controlled-time! (f)))