diff --git a/src/main/frontend/db/subs_loader.cljs b/src/main/frontend/db/subs_loader.cljs index 9f63986..40061df 100644 --- a/src/main/frontend/db/subs_loader.cljs +++ b/src/main/frontend/db/subs_loader.cljs @@ -8,6 +8,22 @@ (defonce ^:private *batch (atom {})) +(defonce ^:private *stats (atom {:dedup-hits 0 :new-entries 0 :flushes 0 :batch-sizes {}})) + +(defn get-stats + "Snapshot of subs-loader batching counters: :dedup-hits counts load! calls + that reused an already-pending slot request within the same unflushed + batch window (see `load!`); :batch-sizes tallies entries per slot kind + across flushes. Dev-only instrumentation for the server-client migration + latency baseline (see docs/agent-guide); does not affect batching or the + `limits` above." + [] + @*stats) + +(defn reset-stats! + [] + (reset! *stats {:dedup-hits 0 :new-entries 0 :flushes 0 :batch-sizes {}})) + (defn- reject! [entries error] (doseq [{:keys [result]} entries] @@ -45,6 +61,13 @@ [] (when @state/db-worker-ready? (let [batch (take-batch!)] + (swap! *stats + (fn [s] + (-> s + (update :flushes inc) + (update :batch-sizes + #(merge-with + % + (frequencies (map (comp slot-kind first :slot-key) batch))))))) (doseq [[graph-id graph-entries] (group-by :graph-id batch) entries (request-groups graph-entries)] (-> (state/ (p/let [result (apply worker qkw args)] + (if (or (instance? ExceptionInfo result) + (instance? js/Error result)) + (p/rejected result) + result)) + (p/finally (fn [] (record-invoke-stat! qkw (- (js/performance.now) started-at)))))))) (def ^:private export-block-text-indent-styles #{"dashes" "spaces" "no-indent"}) diff --git a/src/main/frontend/worker/db_worker_node.cljs b/src/main/frontend/worker/db_worker_node.cljs index f5f94e7..e6b0185 100644 --- a/src/main/frontend/worker/db_worker_node.cljs +++ b/src/main/frontend/worker/db_worker_node.cljs @@ -20,6 +20,25 @@ (defonce ^:private *sse-clients (atom #{})) (defonce ^:private *lock-info (atom nil)) (defonce ^:private *server-list-file (atom nil)) +(defonce ^:private *inflight-by-repo (atom {})) +(defonce ^:private *max-inflight-by-repo (atom {})) + +(defn- invoke-started! + "Increments the /v1/invoke in-flight counter for repo and logs a new + concurrency high-water mark when observed. Dev-only instrumentation for the + server-client migration multi-client baseline (see docs/agent-guide); has no + effect on request handling." + [repo] + (let [n (get (swap! *inflight-by-repo update repo (fnil inc 0)) repo) + prev-max (get @*max-inflight-by-repo repo 0)] + (when (> n prev-max) + (swap! *max-inflight-by-repo assoc repo n) + (log/info :db-worker-node-invoke-concurrency-high-water-mark + {:repo repo :concurrent n})))) + +(defn- invoke-finished! + [repo] + (swap! *inflight-by-repo update repo (fnil dec 0))) (defn- server-list-file-path [root-dir] @@ -376,7 +395,9 @@ (p/let [_ (when-not (contains? non-repo-methods method-kw) (let [{:keys [path lock]} @*lock-info] (db-lock/assert-lock-owner! path lock))) - result ( (