enhance(rtc): cleanup finished client ops every 3 hours

This commit is contained in:
Tienson Qin
2026-03-24 14:22:07 +08:00
parent 183a7963bf
commit b54a73f298
5 changed files with 134 additions and 1 deletions

View File

@@ -81,6 +81,46 @@
(is (nil? (get @search/fuzzy-search-indices test-repo)))
(is (nil? (get @worker-state/*sqlite-conns test-repo)))))))
(deftest client-ops-cleanup-timer-starts-once-and-clears-on-close-test
(restoring-worker-state
(fn []
(let [scheduled (atom [])
cleared (atom [])
original-set-interval js/setInterval
original-clear-interval js/clearInterval
fake-db #js {:close (fn [] nil)}
timer-id #js {:id "timer-1"}]
(set! js/setInterval
(fn [f interval-ms]
(swap! scheduled conj {:fn f :interval-ms interval-ms})
timer-id))
(set! js/clearInterval
(fn [id]
(swap! cleared conj id)))
(try
(reset! worker-state/*sqlite-conns
{test-repo {:db fake-db
:search fake-db
:client-ops fake-db}})
(reset! worker-state/*datascript-conns {test-repo :datascript})
(reset! worker-state/*client-ops-conns {test-repo :client-ops})
(reset! (deref #'db-worker/*client-ops-cleanup-timers) {})
(#'db-worker/ensure-client-ops-cleanup-timer! test-repo)
(#'db-worker/ensure-client-ops-cleanup-timer! test-repo)
(is (= 1 (count @scheduled)))
(is (= (* 3 60 60 1000) (:interval-ms (first @scheduled))))
(is (= timer-id (get @(deref #'db-worker/*client-ops-cleanup-timers) test-repo)))
(db-worker/close-db! test-repo)
(is (= [timer-id] @cleared))
(is (nil? (get @(deref #'db-worker/*client-ops-cleanup-timers) test-repo)))
(finally
(set! js/setInterval original-set-interval)
(set! js/clearInterval original-clear-interval)))))))
(deftest complete-datoms-import-invalidates-existing-search-db-test
(async done
(restoring-worker-state

View File

@@ -1,5 +1,5 @@
(ns frontend.worker.sync.client-op-test
(:require [cljs.test :refer [deftest is]]
(:require [cljs.test :refer [deftest is testing]]
[datascript.core :as d]
[frontend.worker.state :as worker-state]
[frontend.worker.sync.client-op :as client-op]))
@@ -17,3 +17,40 @@
(is (= #{"graph-2"} (set (map :v graph-uuid-datoms)))))
(finally
(reset! worker-state/*client-ops-conns prev-client-ops-conns)))))
(deftest cleanup-finished-history-ops-removes-only-unreferenced-finished-txs-test
(let [repo "repo-cleanup"
conn (d/create-conn client-op/schema-in-db)
prev-client-ops-conns @worker-state/*client-ops-conns
keep-tx-id (random-uuid)
remove-tx-id (random-uuid)
pending-tx-id (random-uuid)]
(reset! worker-state/*client-ops-conns {repo conn})
(try
(d/transact! conn
[{:db-sync/tx-id keep-tx-id
:db-sync/pending? false}
{:db-sync/tx-id remove-tx-id
:db-sync/pending? false}
{:db-sync/tx-id pending-tx-id
:db-sync/pending? true}
{:db-ident :metadata/local
:local-tx 99}])
(is (= 1 (client-op/cleanup-finished-history-ops! repo #{keep-tx-id})))
(is (some? (d/entity @conn [:db-sync/tx-id keep-tx-id])))
(is (nil? (d/entity @conn [:db-sync/tx-id remove-tx-id])))
(is (some? (d/entity @conn [:db-sync/tx-id pending-tx-id])))
(is (= 99 (:local-tx (d/entity @conn [:db-ident :metadata/local]))))
(finally
(reset! worker-state/*client-ops-conns prev-client-ops-conns)))))
(deftest cleanup-finished-history-ops-no-conn-is-noop-test
(let [repo "repo-no-conn"
prev-client-ops-conns @worker-state/*client-ops-conns]
(reset! worker-state/*client-ops-conns {})
(try
(testing "cleanup should be safe when client-ops conn is missing"
(is (= 0 (client-op/cleanup-finished-history-ops! repo #{}))))
(finally
(reset! worker-state/*client-ops-conns prev-client-ops-conns)))))