 
 (def trace-cbs (atom {}))
 (defonce traces (atom []))
+(defonce next-delivery (atom 0))
 
 (defn register-trace-cb
   "Registers a tracing callback function which will receive a collection of one or more traces.

   :child-of  (or child-of (:id *current-trace*))
   :start     (interop/now)})

(defn debounce [f interval]
  #?(:cljs (goog.functions/debounce f interval)
     :clj  (f)))

(def run-tracing-callbacks!
  (debounce
    (fn tracing-cb-debounced []
      (doseq [[k cb] @trace-cbs]

             #?(:cljs (catch :default e
                        (console :error "Error thrown from trace cb" k "while storing" @traces e)))))
      (reset! traces []))
    debounce-time))

(defn run-tracing-callbacks! [now]
  ;; Optimised debounce, we only re-debounce
  ;; if we are close to delivery time
  ;; to avoid constant setting and cancelling
  ;; timeouts.

  ;; If we are within 10 ms of next delivery
  (when (< (- @next-delivery 10) now)
    (schedule-debounce)
    ;; The next-delivery time is not perfectly accurate
    ;; as scheduling the debounce takes some time, but
    ;; it's good enough for our purposes here.
    (reset! next-delivery (+ now debounce-time))))

(macros/deftime
  (defmacro finish-trace [trace]
