Incrementally parse traces

Rather than re-parsing them every time we get a new set of
traces. This is much more efficient and lets us do more useful things
in the future.
This commit is contained in:
Daniel Compton 2018-01-28 10:46:02 +13:00
parent af4afbae88
commit 631fa68448
2 changed files with 59 additions and 57 deletions

View File

@ -485,34 +485,35 @@
(rf/reg-event-db
:epochs/receive-new-traces
(fn [db [_ new-traces]]
(if-let [new-traces (->> (filter log-trace? new-traces)
(sort-by :id))]
(if-let [filtered-traces (->> (filter log-trace? new-traces)
(sort-by :id))]
(let [number-of-epochs-to-retain (get-in db [:settings :number-of-epochs])
events-to-ignore (->> (get-in db [:settings :ignored-events]) vals (map :event-id) set)
previous-traces (get-in db [:traces :all-traces] [])
all-traces (reduce conj previous-traces new-traces)
matches (:matches (metam/parse-traces all-traces))
matches (remove (fn [match]
parse-state (get-in db [:epochs :parse-state] metam/initial-parse-state)
all-traces (reduce conj previous-traces filtered-traces)
parse-state (metam/parse-traces parse-state filtered-traces)
new-matches (:partitions parse-state)
previous-matches (get-in db [:epochs :matches] [])
parse-state (assoc parse-state :partitions []) ;; Remove matches we know about
new-matches (remove (fn [match]
(let [event (get-in (metam/matched-event match) [:tags :event])]
(contains? events-to-ignore (first event)))) matches)
retained-epochs (take-last number-of-epochs-to-retain matches)
first-id-to-retain (:id (ffirst retained-epochs))
(contains? events-to-ignore (first event)))) new-matches)
all-matches (reduce conj previous-matches new-matches)
retained-matches (into [] (take-last number-of-epochs-to-retain all-matches))
first-id-to-retain (:id (ffirst retained-matches))
retained-traces (into [] (drop-while #(< (:id %) first-id-to-retain)) all-traces)]
(rf/dispatch [:epochs/update-epochs {:matches retained-epochs}])
(assoc-in db [:traces :all-traces] retained-traces))
(-> db
(assoc-in [:traces :all-traces] retained-traces)
(update :epochs (fn [epochs]
(assoc epochs
:matches retained-matches
:matches-by-id (into {} (map (juxt first-match-id identity)) retained-matches)
:match-ids (mapv first-match-id retained-matches)
:parse-state parse-state)))))
;; Else
db)))
(rf/reg-event-db
:epochs/update-epochs
[(rf/path [:epochs])]
(fn [epochs [_ rt]]
(let [matches (:matches rt)]
(assoc epochs
:matches matches
:matches-by-id (into {} (map (juxt first-match-id identity)) matches)
:match-ids (mapv first-match-id matches)))))
(rf/reg-event-fx
:epochs/previous-epoch
[(rf/path [:epochs])]

View File

@ -185,50 +185,51 @@
(defn quiescent? [event]
(= :reagent/quiescent (:op-type event)))
(defn parse-traces [traces]
(let [partitions (reduce
(fn [state event]
(let [current-match (:current-match state)
previous-event (:previous-event state)
no-match? (nil? current-match)]
(-> (cond
(def initial-parse-state
{:current-match nil
:previous-event nil
:partitions []})
;; No current match yet, check if this is the start of an epoch
no-match?
(if (start-of-epoch? event)
(assoc state :current-match [event])
state)
(defn parse-traces [parse-state traces]
(reduce
(fn [state event]
(let [current-match (:current-match state)
previous-event (:previous-event state)
no-match? (nil? current-match)]
(-> (cond
;; We are in an epoch match, and reagent has gone to a quiescent state
(quiescent? event)
(-> state
(update :partitions conj (conj current-match event))
(assoc :current-match nil))
;; No current match yet, check if this is the start of an epoch
no-match?
(if (start-of-epoch? event)
(assoc state :current-match [event])
state)
;; We are in an epoch match, and we have started a new epoch
;; The previously seen event was the last event of the old epoch,
;; and we need to start a new one from this event.
(start-of-epoch-and-prev-end? event state)
(-> state
(update :partitions conj (conj current-match previous-event))
(assoc :current-match [event]))
;; We are in an epoch match, and reagent has gone to a quiescent state
(quiescent? event)
(-> state
(update :partitions conj (conj current-match event))
(assoc :current-match nil))
(event-run? event)
(update state :current-match conj event)
;; We are in an epoch match, and we have started a new epoch
;; The previously seen event was the last event of the old epoch,
;; and we need to start a new one from this event.
(start-of-epoch-and-prev-end? event state)
(-> state
(update :partitions conj (conj current-match previous-event))
(assoc :current-match [event]))
(event-run? event)
(update state :current-match conj event)
:else
state
;; Add a timeout/warning if a match goes on for more than a second?
:else
state
;; Add a timeout/warning if a match goes on for more than a second?
)
(assoc :previous-event event))))
{:current-match nil
:previous-event nil
:partitions []}
traces)
matches (:partitions partitions)]
{:matches matches}))
)
(assoc :previous-event event))))
parse-state
traces))
(defn matched-event [match]
(->> match