(ns metabase.query-analysis.failure-map (:import (java.util.concurrent ConcurrentHashMap) (java.util.function BiFunction))) | |
(set! *warn-on-reflection* true) | |
(def ^:private ^ConcurrentHashMap cached-failures (ConcurrentHashMap.)) | |
(def ^:private max-size 10000) | |
(def ^:private max-retries 2) | |
(defn- ->query-hash [card] (hash (:dataset_query card))) | |
Used by tests | (defn reset-map! [] (.clear cached-failures)) |
Record when we have failed to analyze a given version of a card, to prevent endless retrying. | (defn track-failure! [card] ;; This size operation is close to constant time at the moment - watch out if you change the data structure. (.compute cached-failures (:id card) (reify BiFunction (apply [_this _k existing] (let [hsh (->query-hash card)] (if (= hsh (:query-hash existing)) (update existing :retries-remaining #(max 0 (dec %))) (when (< (.size cached-failures) max-size) {:query-hash hsh :retries-remaining (dec max-retries)}))))))) |
Once we manage to analyze a card, we can forget about previous failures. | (defn track-success! [card] (.remove cached-failures (:id card))) |
Should we skip retrying the given card because it has failed too many times? | (defn non-retryable? [card] (boolean (when-let [{:keys [retries-remaining query-hash]} (.get cached-failures (:id card))] (and (zero? retries-remaining) (= query-hash (->query-hash card)))))) |