|
7 | 7 | [taoensso.timbre :as log]
|
8 | 8 | [clojure.core.async :refer [<! go go-loop] :as async]
|
9 | 9 | [progrock.core :as pr]
|
10 |
| - [kixi.stats.core :as kixi] |
11 | 10 | [doric.core :refer [table]]
|
12 | 11 | [ring.util.codec :as ring.codec]
|
13 | 12 | [manetu.sparql-loadtest.binding-loader :as binding-loader]
|
14 |
| - [manetu.sparql-loadtest.driver.api :as driver.api])) |
| 13 | + [manetu.sparql-loadtest.driver.api :as driver.api] |
| 14 | + [manetu.sparql-loadtest.stats :as stats])) |
15 | 15 |
|
16 | 16 | (defn execute-query
|
17 | 17 | [{:keys [driver] :as ctx} query bindings]
|
|
72 | 72 | (let [result (<! (async/transduce xform f (f) ch))]
|
73 | 73 | (resolve result)))))))
|
74 | 74 |
|
75 |
| -(defn compute-summary-stats |
76 |
| - [options n mux] |
77 |
| - (transduce-promise options n mux (map :duration) kixi/summary)) |
| 75 | +(defn round2 |
| 76 | + "Round a double to the given precision (number of significant digits)" |
| 77 | + [precision ^double d] |
| 78 | + (let [factor (Math/pow 10 precision)] |
| 79 | + (/ (Math/round (* d factor)) factor))) |
78 | 80 |
|
79 | 81 | (defn successful?
|
80 | 82 | [{:keys [success]}]
|
|
84 | 86 | [{:keys [success]}]
|
85 | 87 | (false? success))
|
86 | 88 |
|
87 |
| -(defn count-msgs |
88 |
| - [ctx n mux pred] |
89 |
| - (transduce-promise ctx n mux (filter pred) kixi/count)) |
| 89 | +(defn rows-pred? |
| 90 | + [pred {{:keys [rows]} :result :as x}] |
| 91 | + (log/debug "x:" x) |
| 92 | + (pred rows)) |
| 93 | + |
| 94 | +(def zero-rows? (partial rows-pred? zero?)) |
| 95 | +(def some-rows? (partial rows-pred? pos?)) |
| 96 | + |
| 97 | +(defn compute-summary-stats |
| 98 | + [options n mux pred] |
| 99 | + (-> (transduce-promise options n mux (comp (filter pred) (map :duration)) stats/summary) |
| 100 | + (p/then (fn [{:keys [dist] :as summary}] |
| 101 | + (-> summary |
| 102 | + (dissoc :dist) |
| 103 | + (merge dist) |
| 104 | + (as-> $ (m/map-vals #(round2 2 (or % 0)) $))))))) |
90 | 105 |
|
91 | 106 | (defn compute-stats
|
92 | 107 | [ctx n mux]
|
93 |
| - (-> (p/all [(compute-summary-stats ctx n mux) |
94 |
| - (count-msgs ctx n mux successful?) |
95 |
| - (count-msgs ctx n mux failed?)]) |
96 |
| - (p/then (fn [[summary s f]] (assoc summary :successes s :failures f))))) |
97 |
| - |
98 |
| -(defn round2 |
99 |
| - "Round a double to the given precision (number of significant digits)" |
100 |
| - [precision ^double d] |
101 |
| - (let [factor (Math/pow 10 precision)] |
102 |
| - (/ (Math/round (* d factor)) factor))) |
| 108 | + (-> (p/all (conj (map (partial compute-summary-stats ctx n mux) |
| 109 | + [failed? |
| 110 | + (every-pred successful? zero-rows?) |
| 111 | + (every-pred successful? some-rows?) |
| 112 | + identity]))) |
| 113 | + (p/then (fn [[failed no-data data total :as summaries]] |
| 114 | + (log/trace "summaries:" summaries) |
| 115 | + (let [failures (get failed :count)] |
| 116 | + {:failures failures :summaries [(assoc failed :description "Errors") |
| 117 | + (assoc no-data :description "Not found") |
| 118 | + (assoc data :description "Successes") |
| 119 | + (assoc total :description "Total")]}))))) |
103 | 120 |
|
104 | 121 | (defn render
|
105 |
| - [ctx {:keys [failures] :as stats}] |
106 |
| - (let [stats (m/map-vals (partial round2 2) stats)] |
107 |
| - (println (table [:successes :failures :min :q1 :median :q3 :max :total-duration :rate] [stats])) |
108 |
| - (if (pos? failures) |
109 |
| - -1 |
110 |
| - 0))) |
| 122 | + [{:keys [nr] :as ctx} {:keys [total-duration summaries] :as stats}] |
| 123 | + (println (table [:description :count :min :mean :stddev :p50 :p90 :p99 :max :rate] (map #(update % :count (fn [count] (str (int count) " (" (* (/ count nr) 100) "%)"))) summaries))) |
| 124 | + (println "Total Duration:" (str total-duration "msecs"))) |
111 | 125 |
|
112 | 126 | (defn process
|
113 | 127 | [{:keys [concurrency nr] :as ctx}]
|
|
119 | 133 | (show-progress ctx nr mux)
|
120 | 134 | (compute-stats ctx nr mux)])
|
121 | 135 | (p/then
|
122 |
| - (fn [[start _ _ {:keys [successes] :as stats}]] |
| 136 | + (fn [[start _ _ stats]] |
123 | 137 | (let [end (t/now)
|
124 | 138 | d (t/duration end start)]
|
125 |
| - (assoc stats :total-duration d :rate (* (/ successes d) 1000))))) |
126 |
| - (p/then (partial render ctx))))) |
| 139 | + (-> stats |
| 140 | + (update :summaries (fn [summaries] |
| 141 | + (map (fn [{:keys [count] :as summary}] |
| 142 | + (assoc summary :rate (round2 2 (* (/ count d) 1000)))) |
| 143 | + summaries))) |
| 144 | + (assoc :total-duration d))))) |
| 145 | + (p/then (fn [{:keys [failures] :as stats}] |
| 146 | + (render ctx stats) |
| 147 | + (if (pos? failures) |
| 148 | + -1 |
| 149 | + 0)))))) |
0 commit comments