Make sure that tracing is eliminated by Closure DCE

This commit is contained in:
Daniel Compton 2016-11-28 22:07:23 +13:00
parent 50e87fd5a6
commit 4d8a311134
3 changed files with 44 additions and 28 deletions

View File

@ -5,12 +5,17 @@
- [#233](https://github.com/Day8/re-frame/issues/233) Added a new builtin effect handler for de-bouncing events
- [#218](https://github.com/Day8/re-frame/issues/218) Make it okay to use `subscribe` in Form-1 components
#### Breaking
- Due to the new tracing features using `goog-define` (described below), re-frame now requires ClojureScript 1.7.48 or above. See [Parameterizing ClojureScript Builds](https://www.martinklepsch.org/posts/parameterizing-clojurescript-builds.html) for more information.
#### Improvements
- [#200](https://github.com/Day8/re-frame/pull/200) Remove trailing spaces from console logging
- [#248](https://github.com/Day8/re-frame/pull/200) Provide after interceptor with `db` coeffect, if no `db` effect was produced.
- Add re-frame.loggers/get-loggers function to well, you know.
- Added `clear-subscription-cache!` function. This should be used when hot reloading code to ensure that any bad subscriptions that cause rendering exceptions are removed. See [reagent-project/reagent#272](https://github.com/reagent-project/reagent/issues/272) for more details on this.
- Added experimental tracing features. These are subject to change and undocumented at the moment. By default they are disabled, and will be completely compiled out by advanced optimisations. To enable them, set a [`:closure-defines`](https://www.martinklepsch.org/posts/parameterizing-clojurescript-builds.html) key to `{"re_frame.trace.trace_enabled_QMARK_" true}`
#### Fixes

View File

@ -61,7 +61,8 @@
:output-dir "run/compiled/karma/test"
:optimizations :whitespace
:main "re_frame.test_runner"
:pretty-print true}}]}
:pretty-print true
:closure-defines {"re_frame.trace.trace_enabled_QMARK_" true}}}]}
:aliases {"test-once" ["do" "clean," "cljsbuild" "once" "test," "shell" "open" "test/test.html"]
"test-auto" ["do" "clean," "cljsbuild" "auto" "test,"]

View File

@ -2,14 +2,22 @@
"Tracing for re-frame.
Alpha quality, subject to change/break at any time."
(:require [re-frame.interop :as interop]
[re-frame.loggers :refer [console]]
[clojure.string :as str]))
[re-frame.loggers :refer [console]]))
(def id (atom 0))
(def ^:dynamic *current-trace* nil)
(defn reset-tracing! []
(reset! id 0))
#?(:cljs (goog-define trace-enabled? false)
:clj (def ^boolean trace-enabled? false))
(defn ^boolean is-trace-enabled?
"See https://groups.google.com/d/msg/clojurescript/jk43kmYiMhA/IHglVr_TPdgJ for more details"
[]
trace-enabled?)
(def trace-cbs (atom {}))
(defn register-trace-cb
@ -32,35 +40,37 @@
:child-of (or child-of (:id *current-trace*))
:start (interop/now)})
(defn finish-trace [trace]
(let [end (interop/now)
duration (- end (:start trace))]
(doseq [[k cb] @trace-cbs]
(try (cb [(assoc trace
:duration duration
:end (interop/now))])
(catch #?(:cljs :default :clj Exception) e
(console :error "Error thrown from trace cb" k "while storing" trace e))))))
#?(:clj (defmacro finish-trace [trace]
`(when (is-trace-enabled?)
(let [end# (interop/now)
duration# (- end# (:start ~trace))]
(doseq [[k# cb#] @trace-cbs]
(try (cb# [(assoc ~trace
:duration duration#
:end (interop/now))])
#?(:clj (catch Exception e#
(console :error "Error thrown from trace cb" k# "while storing" ~trace e#)))
#?(:cljs (catch :default e#
(console :error "Error thrown from trace cb" k# "while storing" ~trace e#)))))))))
#?(:clj (defmacro with-trace
"Create a trace inside the scope of the with-trace macro
Common keys:
Common keys for trace-opts
:op-type - what kind of operation is this? e.g. :sub/create, :render.
:operation - identifier for the operation, for an subscription it would be the subscription keyword
tags - a map of arbitrary kv pairs"
;; TODO: compile it out under normal circumstances
[{:keys [operation op-type tags child-of] :as trace-opts} & body]
`(binding [*current-trace* (start-trace ~trace-opts)]
(try ~@body
(finally (finish-trace *current-trace*))))))
`(if (is-trace-enabled?)
(binding [*current-trace* (start-trace ~trace-opts)]
(try ~@body
(finally (finish-trace *current-trace*))))
(do ~@body))))
(defn merge-trace! [m]
;; Overwrite keys in tags, and all top level keys.
(let [new-trace (-> (update *current-trace* :tags merge (:tags m))
(merge (dissoc m :tags)))]
(set! *current-trace* new-trace))
nil)
(defn reset-tracing! []
(reset! id 0))
#?(:clj (defmacro merge-trace! [m]
;; Overwrite keys in tags, and all top level keys.
`(when (is-trace-enabled?)
(let [new-trace# (-> (update *current-trace* :tags merge (:tags ~m))
(merge (dissoc ~m :tags)))]
(set! *current-trace* new-trace#))
nil)))