|
18 | 18 | (defn- profiler-controls []
|
19 | 19 | (let [^String status-msg (core/status)]
|
20 | 20 | (if (.contains status-msg "is running")
|
21 |
| - (format "<form action=\"/stop-profiler\">[%s] profiling is running |
22 |
| - <input type=\"submit\" value=\"Stop profiler\"/></form>" |
| 21 | + (format "<form action='/stop-profiler'>[%s] profiling is running |
| 22 | + <input type='submit' value='Stop profiler'/></form>" |
23 | 23 | (name (@@#'core/start-options :event :cpu)))
|
24 |
| - (format "<form action=\"/start-profiler\">Event: |
25 |
| - <select name=\"event\">%s</select> |
26 |
| - <input type=\"submit\" value=\"Start profiler\"/></form>" |
| 24 | + (format "<form action='/start-profiler'> |
| 25 | + <label for='event'>Event:</label> |
| 26 | + <select id='event' name='event'>%s</select> |
| 27 | + <input type='submit' value='Start profiler'/></form>" |
27 | 28 | (forj [ev (remove #{:ClassName.methodName}
|
28 | 29 | (core/list-event-types {:silent? true}))]
|
29 | 30 | (format "<option value=%s>%s</option>" (name ev) (name ev)))))))
|
|
46 | 47 | (defn- format-size [sz samples]
|
47 | 48 | (let [sz (if (< sz 1024) (str sz " b") (format "%.1f Kb" (/ sz 1024.0)))
|
48 | 49 | samples (cond (nil? samples) nil
|
49 |
| - (< samples 1000) (str "<br>" samples " samples") |
50 |
| - :else (format "<br>%.1fk samples" (/ samples 1e3)))] |
51 |
| - (cond-> sz samples (str samples)))) |
| 50 | + (< samples 1000) (str samples " samples") |
| 51 | + :else (format "%.1fk samples" (/ samples 1e3)))] |
| 52 | + (or samples sz))) |
| 53 | + |
| 54 | +(defn- resolve-stacks-file [short-name] |
| 55 | + (when-let [^File f (some->> short-name (io/file results/root-directory "results"))] |
| 56 | + (when (.exists f) f))) |
52 | 57 |
|
53 | 58 | (defn- file-table [root files]
|
54 | 59 | (let [files (sort-by #(.lastModified ^File %) > files) ;; Newer on top
|
55 | 60 | parsed-files (for [^File f files
|
56 | 61 | :let [info (results/parse-results-filename (.getName f))]]
|
57 | 62 | [f (update info :date #(or % (Date. (.lastModified f))))])
|
58 |
| - grouped (group-by #(date->local-date (:date (second %))) parsed-files)] |
| 63 | + grouped (group-by #(date->local-date (:date (second %))) parsed-files) |
| 64 | + diff-from-file (resolve-stacks-file (@ui-state :diff-from))] |
59 | 65 | (format
|
60 | 66 | "<table><thead>%s</thead><tbody>%s</tbody></table>"
|
61 | 67 | (row :th "heading"
|
|
86 | 92 | id2)
|
87 | 93 | stacks (format "<a href='%s'>raw</a>"
|
88 | 94 | (str root (.getName stacks))))
|
89 |
| - ""))))))) |
| 95 | + (if diff-from-file |
| 96 | + (cond (= diff-from-file stacks) |
| 97 | + "<button class='diff cancel' onclick=\"window.location.href='/cancel-diff'\">Cancel</button>" |
| 98 | + stacks |
| 99 | + (format "<button class='diff' onclick=\"window.location.href='/finish-diff?to=%s'\">...to this</button>" |
| 100 | + (.getName stacks))) |
| 101 | + (when stacks |
| 102 | + (format "<button class='diff' onclick=\"window.location.href='/start-diff?from=%s'\">Diff to...</button>" |
| 103 | + (.getName stacks))))))))))) |
| 104 | + |
| 105 | +(defn- generate-diff [to-file-short-name] |
| 106 | + (let [from-file (resolve-stacks-file (@ui-state :diff-from)) |
| 107 | + to-file (resolve-stacks-file to-file-short-name)] |
| 108 | + (core/generate-diffgraph from-file to-file {}))) |
90 | 109 |
|
91 | 110 | (defn- main-page [root files]
|
92 | 111 | (->> {:profiler-controls (profiler-controls)
|
|
110 | 129 | (do (core/clear-results)
|
111 | 130 | (redirect "/"))
|
112 | 131 |
|
| 132 | + (= path "/start-diff") |
| 133 | + (do (swap! ui-state assoc :diff-from (params "from")) |
| 134 | + (redirect "/")) |
| 135 | + |
| 136 | + (= path "/finish-diff") |
| 137 | + (do (generate-diff (params "to")) |
| 138 | + (swap! ui-state dissoc :diff-from) |
| 139 | + (redirect "/")) |
| 140 | + |
| 141 | + (= path "/cancel-diff") |
| 142 | + (do (swap! ui-state dissoc :diff-from) |
| 143 | + (redirect "/")) |
| 144 | + |
113 | 145 | (= path "/")
|
114 |
| - {:body (main-page path files)} |
| 146 | + (let [files (filter #(= (wwws/get-extension (str %)) "html") files)] |
| 147 | + {:body (main-page path files)}) |
115 | 148 |
|
116 | 149 | (= path "/favicon.png")
|
117 | 150 | {:body (io/resource "favicon.png")
|
|
0 commit comments