/
probe.clj
48 lines (41 loc) · 1.58 KB
/
probe.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
(ns state-flow.probe
(:require [cats.core :as m]
[state-flow.state :as state]))
;;
;; Helper functions for testing
;;
(def default-sleep-time 200)
(def default-times-to-try 5)
(defn ^:private check
"Applies check-fn to the return value of a step, returns the check result and the original value in a map"
[step check-fn]
(m/mlet [value step]
(state/return {:check-result (check-fn value)
:value value})))
(defn ^:private with-delay
"Adds a delay before the step is run"
[step delay]
(m/>> (state/wrap-fn #(Thread/sleep delay)) step))
(defn ^:private sequence-while*
"Like cats.core/sequence but with short circuiting when pred is satisfied by the return value of a step"
[pred acc steps]
(if (empty? steps)
acc
(m/mlet [result (first steps)
results acc]
(if (pred result)
(state/return (conj results result))
(sequence-while* pred (state/return (conj results result)) (rest steps))))))
(defn ^:private sequence-while
[pred steps]
(sequence-while* pred (state/return []) steps))
(defn probe
"Internal use only. Evaluates step repeatedly with check-fn until check-fn succeeds or we try too many times"
([step check-fn]
(probe step check-fn {}))
([step check-fn {:keys [sleep-time times-to-try]
:or {sleep-time default-sleep-time
times-to-try default-times-to-try}}]
(sequence-while :check-result
(cons (check step check-fn)
(repeat (dec times-to-try) (with-delay (check step check-fn) sleep-time))))))