mirror of
https://github.com/logseq/logseq.git
synced 2026-06-01 19:01:22 +00:00
enhance(cli): update db-worker-node options
This commit is contained in:
@@ -22,6 +22,10 @@
|
||||
(defonce ^:private *file-handler (atom nil))
|
||||
(defonce ^:private *server-list-file (atom nil))
|
||||
|
||||
(defn- server-list-file-path
|
||||
[root-dir]
|
||||
(server-list/path root-dir))
|
||||
|
||||
(defn- send-json!
|
||||
[^js res status payload]
|
||||
(.writeHead res status #js {"Content-Type" "application/json"})
|
||||
@@ -54,7 +58,6 @@
|
||||
"--root-dir" (recur (subvec args 2) (assoc opts :root-dir (second args)))
|
||||
"--repo" (recur (subvec args 2) (assoc opts :repo (second args)))
|
||||
"--owner-source" (recur (subvec args 2) (assoc opts :owner-source (second args)))
|
||||
"--server-list-file" (recur (subvec args 2) (assoc opts :server-list-file (second args)))
|
||||
"--log-level" (recur (subvec args 2) (assoc opts :log-level (second args)))
|
||||
"--create-empty-db" (recur (subvec args 1) (assoc opts :create-empty-db? true))
|
||||
"--version" (recur (subvec args 1) (assoc opts :version? true))
|
||||
@@ -354,7 +357,7 @@
|
||||
(defn- show-help!
|
||||
[]
|
||||
(println (str (style/bold "db-worker-node") " " (style/bold "options") ":"))
|
||||
(println (str " " (style/bold "--root-dir") " <path> (default ~/logseq)"))
|
||||
(println (str " " (style/bold "--root-dir") " <path> (required)"))
|
||||
(println (str " " (style/bold "--repo") " <name> (required)"))
|
||||
(println (str " " (style/bold "--create-empty-db") " (start with empty initial datoms)"))
|
||||
(println (str " " (style/bold "--log-level") " <level> (default info)"))
|
||||
@@ -453,15 +456,115 @@
|
||||
(swap! *lock-info assoc :lock updated-lock)
|
||||
nil))
|
||||
|
||||
(defn- close-server!
|
||||
[server]
|
||||
(p/create
|
||||
(fn [resolve _]
|
||||
(try
|
||||
(.close server (fn [] (resolve true)))
|
||||
(catch :default _
|
||||
(resolve true))))))
|
||||
|
||||
(defn- clear-runtime-state!
|
||||
[actual-port]
|
||||
(reset! *ready? false)
|
||||
(when-let [file-path @*server-list-file]
|
||||
(server-list/remove-entry! file-path {:pid (.-pid js/process)
|
||||
:port actual-port}))
|
||||
(doseq [^js res @*sse-clients]
|
||||
(try
|
||||
(.end res)
|
||||
(catch :default _)))
|
||||
(reset! *sse-clients #{})
|
||||
(when-let [lock-path (:path @*lock-info)]
|
||||
(db-lock/remove-lock! lock-path)))
|
||||
|
||||
(defn- make-stop!
|
||||
[{:keys [proxy repo actual-port server stopped? on-stopped!]}]
|
||||
(fn []
|
||||
(if @stopped?
|
||||
(p/resolved true)
|
||||
(do
|
||||
(reset! stopped? true)
|
||||
(-> (p/let [_ (<close-bound-repo! proxy repo)]
|
||||
(clear-runtime-state! actual-port)
|
||||
(close-server! server)
|
||||
true)
|
||||
(p/finally
|
||||
(fn []
|
||||
(when (fn? on-stopped!)
|
||||
(on-stopped!)))))))))
|
||||
|
||||
(defn- resolve-listening-daemon!
|
||||
[{:keys [server proxy repo host port* stop!* stopped? on-stopped!]} resolve]
|
||||
(let [address (.address server)
|
||||
actual-port (if (number? address) address (.-port address))
|
||||
_ (reset! port* actual-port)
|
||||
stop! (make-stop! {:proxy proxy
|
||||
:repo repo
|
||||
:actual-port actual-port
|
||||
:server server
|
||||
:stopped? stopped?
|
||||
:on-stopped! on-stopped!})]
|
||||
(reset! *ready? true)
|
||||
(when-let [file-path @*server-list-file]
|
||||
(server-list/append-entry! file-path {:pid (.-pid js/process)
|
||||
:port actual-port}))
|
||||
(reset! stop!* stop!)
|
||||
(resolve {:host host
|
||||
:port actual-port
|
||||
:server server
|
||||
:stop! stop!})))
|
||||
|
||||
(defn- start-http-server!
|
||||
[{:keys [proxy repo host port owner-source root-dir on-stopped!]}]
|
||||
(let [stop!* (atom nil)
|
||||
stopped? (atom false)
|
||||
port* (atom nil)
|
||||
server (make-server proxy {:bound-repo repo
|
||||
:host host
|
||||
:port port*
|
||||
:owner-source owner-source
|
||||
:root-dir root-dir
|
||||
:stop-fn (fn []
|
||||
(when-let [stop! @stop!*]
|
||||
(stop!)))})]
|
||||
(p/create
|
||||
(fn [resolve reject]
|
||||
(.listen server port host
|
||||
(fn []
|
||||
(resolve-listening-daemon! {:server server
|
||||
:proxy proxy
|
||||
:repo repo
|
||||
:host host
|
||||
:port* port*
|
||||
:stop!* stop!*
|
||||
:stopped? stopped?
|
||||
:owner-source owner-source
|
||||
:root-dir root-dir
|
||||
:on-stopped! on-stopped!}
|
||||
resolve)))
|
||||
(.on server "error" (fn [error]
|
||||
(when-let [lock-path (:path @*lock-info)]
|
||||
(db-lock/remove-lock! lock-path))
|
||||
(reject error)))))))
|
||||
|
||||
(defn start-daemon!
|
||||
[{:keys [root-dir repo log-level owner-source on-stopped! server-list-file] :as opts}]
|
||||
[{:keys [root-dir repo log-level owner-source on-stopped!] :as opts}]
|
||||
(let [host "127.0.0.1"
|
||||
port 0
|
||||
owner-source (normalize-owner-source owner-source)]
|
||||
(if-not (seq repo)
|
||||
(cond
|
||||
(not (seq root-dir))
|
||||
(p/rejected (ex-info "root-dir is required" {:code :missing-root-dir}))
|
||||
|
||||
(not (seq repo))
|
||||
(p/rejected (ex-info "repo is required" {:code :missing-repo}))
|
||||
|
||||
:else
|
||||
(try
|
||||
(let [root-dir (root-dir/ensure-root-dir! root-dir)]
|
||||
(let [root-dir (root-dir/ensure-root-dir! root-dir)
|
||||
server-list-file (server-list-file-path root-dir)]
|
||||
(install-file-logger! {:root-dir root-dir
|
||||
:repo repo
|
||||
:log-level (keyword (or log-level "info"))})
|
||||
@@ -483,67 +586,13 @@
|
||||
_ (let [method-kw :thread-api/create-or-open-db
|
||||
method-str (normalize-method-str method-kw)]
|
||||
(<invoke! proxy method-str method-kw false [repo (startup-db-opts opts)]))]
|
||||
(let [stop!* (atom nil)
|
||||
stopped? (atom false)
|
||||
port* (atom nil)
|
||||
server (make-server proxy {:bound-repo repo
|
||||
:host host
|
||||
:port port*
|
||||
:owner-source owner-source
|
||||
:root-dir root-dir
|
||||
:stop-fn (fn []
|
||||
(when-let [stop! @stop!*]
|
||||
(stop!)))})]
|
||||
(p/create
|
||||
(fn [resolve reject]
|
||||
(.listen server port host
|
||||
(fn []
|
||||
(let [address (.address server)
|
||||
actual-port (if (number? address)
|
||||
address
|
||||
(.-port address))
|
||||
_ (reset! port* actual-port)
|
||||
stop! (fn []
|
||||
(if @stopped?
|
||||
(p/resolved true)
|
||||
(do
|
||||
(reset! stopped? true)
|
||||
(-> (p/let [_ (<close-bound-repo! proxy repo)]
|
||||
(reset! *ready? false)
|
||||
(when-let [path @*server-list-file]
|
||||
(server-list/remove-entry! path {:pid (.-pid js/process)
|
||||
:port actual-port}))
|
||||
(doseq [^js res @*sse-clients]
|
||||
(try
|
||||
(.end res)
|
||||
(catch :default _)))
|
||||
(reset! *sse-clients #{})
|
||||
(when-let [lock-path (:path @*lock-info)]
|
||||
(db-lock/remove-lock! lock-path))
|
||||
(p/create
|
||||
(fn [resolve _]
|
||||
(try
|
||||
(.close server (fn [] (resolve true)))
|
||||
(catch :default _
|
||||
(resolve true)))))
|
||||
true)
|
||||
(p/finally
|
||||
(fn []
|
||||
(when (fn? on-stopped!)
|
||||
(on-stopped!))))))))]
|
||||
(reset! *ready? true)
|
||||
(when-let [path @*server-list-file]
|
||||
(server-list/append-entry! path {:pid (.-pid js/process)
|
||||
:port actual-port}))
|
||||
(reset! stop!* stop!)
|
||||
(resolve {:host host
|
||||
:port actual-port
|
||||
:server server
|
||||
:stop! stop!}))))
|
||||
(.on server "error" (fn [error]
|
||||
(when-let [lock-path (:path @*lock-info)]
|
||||
(db-lock/remove-lock! lock-path))
|
||||
(reject error)))))))
|
||||
(start-http-server! {:proxy proxy
|
||||
:repo repo
|
||||
:host host
|
||||
:port port
|
||||
:owner-source owner-source
|
||||
:root-dir root-dir
|
||||
:on-stopped! on-stopped!}))
|
||||
(p/catch (fn [e]
|
||||
(when-let [lock-path (:path @*lock-info)]
|
||||
(db-lock/remove-lock! lock-path))
|
||||
@@ -553,7 +602,7 @@
|
||||
|
||||
(defn main
|
||||
[]
|
||||
(let [{:keys [root-dir repo help? version? owner-source server-list-file] :as opts}
|
||||
(let [{:keys [root-dir repo help? version? owner-source] :as opts}
|
||||
(parse-args (.-argv js/process))]
|
||||
(when help?
|
||||
(show-help!)
|
||||
@@ -561,15 +610,17 @@
|
||||
(when version?
|
||||
(println (worker-version/format-version))
|
||||
(.exit js/process 0))
|
||||
(when-not (seq root-dir)
|
||||
(.error js/console "root-dir is required")
|
||||
(.exit js/process 1))
|
||||
(when-not (seq repo)
|
||||
(show-help!)
|
||||
(.error js/console "repo is required")
|
||||
(.exit js/process 1))
|
||||
(-> (p/let [{:keys [stop!] :as daemon}
|
||||
(start-daemon! {:root-dir root-dir
|
||||
:repo repo
|
||||
:create-empty-db? (:create-empty-db? opts)
|
||||
:owner-source owner-source
|
||||
:server-list-file server-list-file
|
||||
:on-stopped! (fn []
|
||||
(log/info :db-worker-node-stopped nil)
|
||||
(.exit js/process 0))
|
||||
@@ -583,7 +634,7 @@
|
||||
code (:code data)
|
||||
message (or (.-message error) (str error))]
|
||||
(cond
|
||||
(= :root-dir-permission code)
|
||||
(#{:missing-root-dir :root-dir-permission} code)
|
||||
(.error js/console message)
|
||||
|
||||
(or (string/includes? message ".node")
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
["fs" :as fs]
|
||||
["path" :as node-path]
|
||||
[logseq.cli.output-mode :as output-mode]
|
||||
[logseq.cli.root-dir :as root-dir]))
|
||||
[logseq.cli.root-dir :as root-dir]
|
||||
[logseq.db-worker.server-list :as server-list]))
|
||||
|
||||
(defn- parse-int
|
||||
[value]
|
||||
@@ -38,7 +39,7 @@
|
||||
|
||||
(defn server-list-path
|
||||
[root-dir]
|
||||
(node-path/join (or root-dir (root-dir/default-root-dir)) "server-list"))
|
||||
(server-list/path (or root-dir (root-dir/default-root-dir))))
|
||||
|
||||
(def ^:private removed-config-keys
|
||||
#{:auth-token :retries :e2ee-password})
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
[clojure.string :as string]
|
||||
[frontend.worker.db-worker-node-lock :as db-lock]
|
||||
[lambdaisland.glogi :as log]
|
||||
[logseq.cli.config :as cli-config]
|
||||
[logseq.cli.profile :as profile]
|
||||
[logseq.cli.root-dir :as root-dir]
|
||||
[logseq.common.config :as common-config]
|
||||
@@ -55,7 +54,7 @@
|
||||
|
||||
(defn- server-list-path
|
||||
[config]
|
||||
(cli-config/server-list-path (resolve-root-dir config)))
|
||||
(server-list/path (resolve-root-dir config)))
|
||||
|
||||
(defn db-worker-dev-script-path
|
||||
[]
|
||||
@@ -145,12 +144,11 @@
|
||||
(assoc payload :http-status status)))
|
||||
|
||||
(defn- spawn-server!
|
||||
[{:keys [repo root-dir owner-source create-empty-db? server-list-file]}]
|
||||
[{:keys [repo root-dir owner-source create-empty-db?]}]
|
||||
(daemon/spawn-server! {:script (db-worker-script-path)
|
||||
:repo repo
|
||||
:root-dir root-dir
|
||||
:owner-source owner-source
|
||||
:server-list-file server-list-file
|
||||
:create-empty-db? create-empty-db?}))
|
||||
|
||||
(defn- rewrite-lock-owner-source!
|
||||
@@ -232,8 +230,7 @@
|
||||
(let [root-dir (resolve-root-dir config)
|
||||
path (lock-path root-dir repo)
|
||||
requester-owner (requester-owner-source config)
|
||||
profile-session (:profile-session config)
|
||||
server-list-file (server-list-path config)]
|
||||
profile-session (:profile-session config)]
|
||||
(profile/time! profile-session "server.ensure-started"
|
||||
(fn []
|
||||
(ensure-repo-dir! root-dir repo)
|
||||
@@ -248,7 +245,6 @@
|
||||
(spawn-server! {:repo repo
|
||||
:root-dir root-dir
|
||||
:owner-source requester-owner
|
||||
:server-list-file server-list-file
|
||||
:create-empty-db? (:create-empty-db? config)})))
|
||||
(-> (profile/time! profile-session
|
||||
"server.wait-lock"
|
||||
|
||||
@@ -221,11 +221,10 @@
|
||||
:interval-ms 50}))
|
||||
|
||||
(defn spawn-server!
|
||||
[{:keys [script repo root-dir owner-source create-empty-db? server-list-file]}]
|
||||
[{:keys [script repo root-dir owner-source create-empty-db?]}]
|
||||
(let [owner-source (normalize-owner-source owner-source)
|
||||
detached? (not= owner-source :electron)
|
||||
args (clj->js (cond-> [script "--repo" repo "--root-dir" root-dir "--owner-source" (name owner-source)]
|
||||
server-list-file (conj "--server-list-file" server-list-file)
|
||||
create-empty-db? (conj "--create-empty-db")))
|
||||
env (js/Object.assign #js {} (.-env js/process) #js {:ELECTRON_RUN_AS_NODE "1"})]
|
||||
(if-not script
|
||||
|
||||
@@ -4,6 +4,12 @@
|
||||
["fs" :as fs]
|
||||
["path" :as node-path]))
|
||||
|
||||
(defn path
|
||||
[root-dir-path]
|
||||
(when-not (seq root-dir-path)
|
||||
(throw (js/Error. "root-dir is required")))
|
||||
(node-path/join root-dir-path "server-list"))
|
||||
|
||||
(defn- parse-int
|
||||
[value]
|
||||
(when (re-matches #"\d+" value)
|
||||
@@ -21,39 +27,39 @@
|
||||
:port port}))))))
|
||||
|
||||
(defn read-entries
|
||||
[path]
|
||||
(if (and (seq path) (fs/existsSync path))
|
||||
(->> (.toString (fs/readFileSync path) "utf8")
|
||||
[file-path]
|
||||
(if (and (seq file-path) (fs/existsSync file-path))
|
||||
(->> (.toString (fs/readFileSync file-path) "utf8")
|
||||
string/split-lines
|
||||
(keep parse-line)
|
||||
vec)
|
||||
[]))
|
||||
|
||||
(defn rewrite-entries!
|
||||
[path entries]
|
||||
(when (seq path)
|
||||
(fs/mkdirSync (node-path/dirname path) #js {:recursive true})
|
||||
[file-path entries]
|
||||
(when (seq file-path)
|
||||
(fs/mkdirSync (node-path/dirname file-path) #js {:recursive true})
|
||||
(let [payload (if (seq entries)
|
||||
(str (string/join "\n" (map (fn [{:keys [pid port]}]
|
||||
(str pid " " port))
|
||||
entries))
|
||||
"\n")
|
||||
"")]
|
||||
(fs/writeFileSync path payload "utf8"))))
|
||||
(fs/writeFileSync file-path payload "utf8"))))
|
||||
|
||||
(defn append-entry!
|
||||
[path {:keys [pid port] :as entry}]
|
||||
(when (and (seq path) (pos-int? pid) (pos-int? port))
|
||||
(fs/mkdirSync (node-path/dirname path) #js {:recursive true})
|
||||
(fs/appendFileSync path (str pid " " port "\n") "utf8")
|
||||
[file-path {:keys [pid port] :as entry}]
|
||||
(when (and (seq file-path) (pos-int? pid) (pos-int? port))
|
||||
(fs/mkdirSync (node-path/dirname file-path) #js {:recursive true})
|
||||
(fs/appendFileSync file-path (str pid " " port "\n") "utf8")
|
||||
entry))
|
||||
|
||||
(defn remove-entry!
|
||||
[path {:keys [pid port]}]
|
||||
(when (seq path)
|
||||
(let [entries (->> (read-entries path)
|
||||
[file-path {:keys [pid port]}]
|
||||
(when (seq file-path)
|
||||
(let [entries (->> (read-entries file-path)
|
||||
(remove (fn [entry]
|
||||
(and (= pid (:pid entry))
|
||||
(= port (:port entry)))))
|
||||
vec)]
|
||||
(rewrite-entries! path entries))))
|
||||
(rewrite-entries! file-path entries))))
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
(ns electron.db-worker-manager-test
|
||||
(:require [cljs.test :refer [async deftest is]]
|
||||
[electron.db-worker :as db-worker]
|
||||
[logseq.cli.server :as cli-server]
|
||||
[promesa.core :as p]))
|
||||
|
||||
(defn- runtime
|
||||
@@ -238,3 +239,22 @@
|
||||
(p/catch (fn [e]
|
||||
(is false (str "unexpected error: " e))))
|
||||
(p/finally (fn [] (done)))))))
|
||||
|
||||
(deftest managed-daemon-start-uses-cli-shared-server-path-with-electron-owner
|
||||
(async done
|
||||
(let [captured (atom nil)]
|
||||
(-> (p/with-redefs [cli-server/ensure-server! (fn [config repo]
|
||||
(reset! captured {:config config
|
||||
:repo repo})
|
||||
(p/resolved {:base-url "http://127.0.0.1:9300"
|
||||
:owned? true}))]
|
||||
((get db-worker/manager :start-daemon!) "graph-a"))
|
||||
(p/then (fn [runtime-info]
|
||||
(is (= "graph-a" (:repo @captured)))
|
||||
(is (= :electron (get-in @captured [:config :owner-source])))
|
||||
(is (nil? (get-in @captured [:config :server-list-file])))
|
||||
(is (= "http://127.0.0.1:9300" (:base-url runtime-info)))
|
||||
(is (= true (:owned? runtime-info)))))
|
||||
(p/catch (fn [e]
|
||||
(is false (str "unexpected error: " e))))
|
||||
(p/finally (fn [] (done)))))))
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
[clojure.string :as string]
|
||||
[frontend.test.node-helper :as node-helper]
|
||||
[frontend.worker.db-core :as db-core]
|
||||
[frontend.worker.db-worker-node-lock :as db-lock]
|
||||
[frontend.worker.db-worker-node :as db-worker-node]
|
||||
[frontend.worker.db-worker-node-lock :as db-lock]
|
||||
[frontend.worker.platform.node :as platform-node]
|
||||
[goog.object :as gobj]
|
||||
[logseq.cli.config :as cli-config]
|
||||
@@ -156,6 +156,36 @@
|
||||
(reset-daemon-state!)
|
||||
(quiet-debug-output-after))
|
||||
|
||||
(defn- run-main-with-overrides
|
||||
[{:keys [argv on-exit on-log on-error start-daemon-fn]}]
|
||||
(test-helper/with-js-property-override
|
||||
js/process
|
||||
"argv"
|
||||
argv
|
||||
(fn []
|
||||
(test-helper/with-js-property-override
|
||||
js/process
|
||||
"exit"
|
||||
on-exit
|
||||
(fn []
|
||||
(test-helper/with-js-property-override
|
||||
js/console
|
||||
"log"
|
||||
on-log
|
||||
(fn []
|
||||
(test-helper/with-js-property-override
|
||||
js/console
|
||||
"error"
|
||||
on-error
|
||||
(fn []
|
||||
(p/with-redefs [db-worker-node/start-daemon! start-daemon-fn]
|
||||
(p/resolved
|
||||
(try
|
||||
(db-worker-node/main)
|
||||
(catch :default e
|
||||
(when-not (= "process-exit" (.-message e))
|
||||
(throw e)))))))))))))))
|
||||
|
||||
(use-fixtures :each {:before normalize-db-worker-state-before
|
||||
:after normalize-db-worker-state-after})
|
||||
|
||||
@@ -282,13 +312,15 @@
|
||||
(is (= "logseq_db_parse_args" (:repo result)))
|
||||
(is (= true (:create-empty-db? result)))))
|
||||
|
||||
(deftest db-worker-node-parse-args-recognizes-server-list-file
|
||||
(deftest db-worker-node-parse-args-ignores-server-list-file
|
||||
(let [parse-args #'db-worker-node/parse-args
|
||||
result (parse-args #js ["node" "dist/db-worker-node.js"
|
||||
"--repo" "logseq_db_parse_args"
|
||||
"--root-dir" "/tmp/logseq-root"
|
||||
"--server-list-file" "/tmp/server-list"])]
|
||||
(is (= "logseq_db_parse_args" (:repo result)))
|
||||
(is (= "/tmp/server-list" (:server-list-file result)))))
|
||||
(is (= "/tmp/logseq-root" (:root-dir result)))
|
||||
(is (nil? (:server-list-file result)))))
|
||||
|
||||
(deftest db-worker-node-parse-args-recognizes-version
|
||||
(let [parse-args #'db-worker-node/parse-args
|
||||
@@ -299,36 +331,92 @@
|
||||
|
||||
(deftest db-worker-node-main-version-exits-early-without-repo
|
||||
(async done
|
||||
(let [exit-code* (atom nil)
|
||||
start-called? (atom false)]
|
||||
(-> (test-helper/with-js-property-override
|
||||
js/process
|
||||
"argv"
|
||||
#js ["node" "dist/db-worker-node.js" "--version"]
|
||||
(fn []
|
||||
(test-helper/with-js-property-override
|
||||
js/process
|
||||
"exit"
|
||||
(fn [code]
|
||||
(reset! exit-code* code)
|
||||
(throw (ex-info "process-exit" {:code code})))
|
||||
(fn []
|
||||
(p/with-redefs [db-worker-node/start-daemon! (fn [_]
|
||||
(reset! start-called? true)
|
||||
(p/rejected (ex-info "should-not-start-daemon" {})))]
|
||||
(p/resolved
|
||||
(let [output (with-out-str
|
||||
(try
|
||||
(db-worker-node/main)
|
||||
(catch :default e
|
||||
(when-not (= "process-exit" (.-message e))
|
||||
(throw e)))))]
|
||||
(is (= 0 @exit-code*))
|
||||
(is (= false @start-called?))
|
||||
(is (string/includes? output "Revision:")))))))))
|
||||
(p/catch (fn [e]
|
||||
(is false (str "unexpected error: " e))))
|
||||
(p/finally done)))))
|
||||
(let [exit-code* (atom nil)
|
||||
start-called? (atom false)]
|
||||
(-> (test-helper/with-js-property-override
|
||||
js/process
|
||||
"argv"
|
||||
#js ["node" "dist/db-worker-node.js" "--version"]
|
||||
(fn []
|
||||
(test-helper/with-js-property-override
|
||||
js/process
|
||||
"exit"
|
||||
(fn [code]
|
||||
(reset! exit-code* code)
|
||||
(throw (ex-info "process-exit" {:code code})))
|
||||
(fn []
|
||||
(p/with-redefs [db-worker-node/start-daemon! (fn [_]
|
||||
(reset! start-called? true)
|
||||
(p/rejected (ex-info "should-not-start-daemon" {})))]
|
||||
(p/resolved
|
||||
(let [output (with-out-str
|
||||
(try
|
||||
(db-worker-node/main)
|
||||
(catch :default e
|
||||
(when-not (= "process-exit" (.-message e))
|
||||
(throw e)))))]
|
||||
(is (= 0 @exit-code*))
|
||||
(is (= false @start-called?))
|
||||
(is (string/includes? output "Revision:")))))))))
|
||||
(p/catch (fn [e]
|
||||
(is false (str "unexpected error: " e))))
|
||||
(p/finally done)))))
|
||||
|
||||
(deftest db-worker-node-main-missing-root-dir-prints-error-and-exits-1
|
||||
(async done
|
||||
(let [exit-code* (atom nil)
|
||||
stdout* (atom [])
|
||||
stderr* (atom [])
|
||||
start-called? (atom false)]
|
||||
(-> (run-main-with-overrides
|
||||
{:argv #js ["node" "dist/db-worker-node.js" "--repo" "logseq_db_missing_root"]
|
||||
:on-exit (fn [code]
|
||||
(reset! exit-code* code)
|
||||
(throw (ex-info "process-exit" {:code code})))
|
||||
:on-log (fn [& args]
|
||||
(swap! stdout* conj (string/join " " args)))
|
||||
:on-error (fn [& args]
|
||||
(swap! stderr* conj (string/join " " args)))
|
||||
:start-daemon-fn (fn [_]
|
||||
(reset! start-called? true)
|
||||
(p/rejected (ex-info "should-not-start-daemon" {})))})
|
||||
(p/then (fn [_]
|
||||
(is (= 1 @exit-code*))
|
||||
(is (= false @start-called?))
|
||||
(is (empty? @stdout*))
|
||||
(is (some #(string/includes? % "root-dir is required")
|
||||
@stderr*))))
|
||||
(p/catch (fn [e]
|
||||
(is false (str "unexpected error: " e))))
|
||||
(p/finally done)))))
|
||||
|
||||
(deftest db-worker-node-main-missing-repo-prints-error-and-exits-1
|
||||
(async done
|
||||
(let [exit-code* (atom nil)
|
||||
stdout* (atom [])
|
||||
stderr* (atom [])
|
||||
start-called? (atom false)]
|
||||
(-> (run-main-with-overrides
|
||||
{:argv #js ["node" "dist/db-worker-node.js" "--root-dir" "/tmp/logseq-root"]
|
||||
:on-exit (fn [code]
|
||||
(reset! exit-code* code)
|
||||
(throw (ex-info "process-exit" {:code code})))
|
||||
:on-log (fn [& args]
|
||||
(swap! stdout* conj (string/join " " args)))
|
||||
:on-error (fn [& args]
|
||||
(swap! stderr* conj (string/join " " args)))
|
||||
:start-daemon-fn (fn [_]
|
||||
(reset! start-called? true)
|
||||
(p/rejected (ex-info "should-not-start-daemon" {})))})
|
||||
(p/then (fn [_]
|
||||
(is (= 1 @exit-code*))
|
||||
(is (= false @start-called?))
|
||||
(is (empty? @stdout*))
|
||||
(is (some #(string/includes? % "repo is required")
|
||||
@stderr*))))
|
||||
(p/catch (fn [e]
|
||||
(is false (str "unexpected error: " e))))
|
||||
(p/finally done)))))
|
||||
|
||||
(deftest db-worker-node-owner-source-cli-is-written-into-lock
|
||||
(async done
|
||||
@@ -406,18 +494,21 @@
|
||||
(is (= {:request-id "r1"}
|
||||
(ldb/read-transit-str (:payload parsed)))))))
|
||||
|
||||
(deftest db-worker-node-help-omits-auth-token
|
||||
(deftest db-worker-node-help-documents-required-root-dir-and-omits-server-list-file
|
||||
(let [show-help! #'db-worker-node/show-help!
|
||||
output (binding [style/*color-enabled?* true]
|
||||
(with-out-str (show-help!)))
|
||||
plain-output (style/strip-ansi output)]
|
||||
(is (not (string/includes? (style/strip-ansi output) "--auth-token")))
|
||||
(is (not (string/includes? plain-output "--rtc-ws-url")))
|
||||
(is (string/includes? plain-output "(default ~/logseq)"))
|
||||
(is (not (string/includes? plain-output "--server-list-file")))
|
||||
(is (not (string/includes? plain-output "(default ~/logseq)")))
|
||||
(is (re-find #"\u001b\[[0-9;]*moptions\u001b\[[0-9;]*m:" output))
|
||||
(is (contains-bold? output "db-worker-node"))
|
||||
(is (contains-bold? output "--root-dir"))
|
||||
(is (contains-bold? output "--repo"))
|
||||
(is (string/includes? plain-output "--root-dir"))
|
||||
(is (string/includes? plain-output "(required)"))
|
||||
(is (string/includes? plain-output "--create-empty-db"))
|
||||
(is (contains-bold? output "--create-empty-db"))
|
||||
(is (not (contains-bold? output "--rtc-ws-url")))
|
||||
@@ -537,12 +628,12 @@
|
||||
(is false (str "unexpected error: " e))))
|
||||
(p/finally done)))))
|
||||
|
||||
(deftest db-worker-node-start-daemon-registers-and-unregisters-server-list-entry
|
||||
(deftest db-worker-node-start-daemon-registers-and-unregisters-derived-server-list-entry
|
||||
(async done
|
||||
(let [data-dir (node-helper/create-tmp-dir "db-worker-server-list")
|
||||
repo (str "logseq_db_server_list_" (subs (str (random-uuid)) 0 8))
|
||||
lock-file-path (lock-path data-dir repo)
|
||||
server-list-file (node-path/join data-dir "server-list")]
|
||||
server-list-file (cli-config/server-list-path data-dir)]
|
||||
(-> (p/with-redefs [platform-node/node-platform (fn [_opts] #js {})
|
||||
db-core/init-core! (fn [_platform]
|
||||
#js {:remoteInvoke (fn [_method _direct-pass? _args]
|
||||
@@ -556,7 +647,6 @@
|
||||
db-lock/update-lock! (fn [_path lock] lock)]
|
||||
(p/let [{:keys [port stop!]} (db-worker-node/start-daemon! {:root-dir data-dir
|
||||
:repo repo
|
||||
:server-list-file server-list-file
|
||||
:log-level "error"})
|
||||
contents-after-start (.toString (fs/readFileSync server-list-file) "utf8")
|
||||
_ (is (string/includes? contents-after-start (str (.-pid js/process) " " port)))
|
||||
@@ -709,14 +799,13 @@
|
||||
(let [daemon (atom nil)
|
||||
data-dir (node-helper/create-tmp-dir "db-worker-daemon")
|
||||
repo (str "logseq_db_smoke_" (subs (str (random-uuid)) 0 8))
|
||||
server-list-file (node-path/join data-dir "server-list")
|
||||
server-list-file (cli-config/server-list-path data-dir)
|
||||
now (js/Date.now)
|
||||
page-uuid (random-uuid)
|
||||
block-uuid (random-uuid)]
|
||||
(-> (p/let [{:keys [host port stop!]}
|
||||
(start-daemon! {:root-dir data-dir
|
||||
:repo repo
|
||||
:server-list-file server-list-file})
|
||||
:repo repo})
|
||||
health (http-get host port "/healthz")
|
||||
missing-readyz (http-get host port "/readyz")
|
||||
health-body (js->clj (js/JSON.parse (:body health)) :keywordize-keys true)
|
||||
@@ -1163,8 +1252,7 @@
|
||||
page-uuid (random-uuid)]
|
||||
(-> (p/let [{:keys [host port stop!]}
|
||||
(start-daemon! {:root-dir data-dir
|
||||
:repo repo
|
||||
:server-list-file server-list-file})
|
||||
:repo repo})
|
||||
_ (reset! daemon {:stop! stop!})
|
||||
_ (invoke host port "thread-api/create-or-open-db" [repo {}])
|
||||
_ (invoke host port "thread-api/transact"
|
||||
|
||||
@@ -60,6 +60,28 @@
|
||||
(is (= (cli-server/db-worker-script-path)
|
||||
(cli-server/db-worker-runtime-script-path))))
|
||||
|
||||
(deftest cli-server-spawn-server-does-not-forward-server-list-file
|
||||
(async done
|
||||
(let [spawn-server! #'cli-server/spawn-server!
|
||||
captured (atom nil)]
|
||||
(-> (p/with-redefs [daemon/spawn-server! (fn [opts]
|
||||
(reset! captured opts)
|
||||
nil)]
|
||||
(p/resolved
|
||||
(spawn-server! {:repo "logseq_db_spawn_test"
|
||||
:root-dir "/tmp/logseq-root"
|
||||
:owner-source :cli
|
||||
:server-list-file "/tmp/server-list"
|
||||
:create-empty-db? true})))
|
||||
(p/then (fn [_]
|
||||
(is (= "logseq_db_spawn_test" (:repo @captured)))
|
||||
(is (= "/tmp/logseq-root" (:root-dir @captured)))
|
||||
(is (= true (:create-empty-db? @captured)))
|
||||
(is (nil? (:server-list-file @captured)))))
|
||||
(p/catch (fn [e]
|
||||
(is false (str "unexpected error: " e))))
|
||||
(p/finally done)))))
|
||||
|
||||
(deftest ensure-server-repairs-stale-lock
|
||||
(async done
|
||||
(let [root-dir (node-helper/create-tmp-dir "cli-server")
|
||||
@@ -290,8 +312,7 @@
|
||||
(is (= (cli-server/resolve-root-dir {:root-dir root-dir})
|
||||
(:root-dir @captured)))
|
||||
(is (= true (:create-empty-db? @captured)))
|
||||
(is (= (cli-config/server-list-path root-dir)
|
||||
(:server-list-file @captured)))))
|
||||
(is (nil? (:server-list-file @captured)))))
|
||||
(p/catch (fn [e]
|
||||
(is false (str "unexpected error: " e))))
|
||||
(p/finally done)))))
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
(when-let [v (get (ns-interns 'logseq.db-worker.daemon) sym)]
|
||||
(apply @v args)))
|
||||
|
||||
(deftest spawn-server-uses-detached-process-and-no-host-port-args
|
||||
(deftest spawn-server-ignores-server-list-file-and-uses-detached-process
|
||||
(let [captured (atom nil)
|
||||
unref-called? (atom false)
|
||||
original-spawn (.-spawn child-process)]
|
||||
@@ -32,8 +32,8 @@
|
||||
(is (= "/tmp/db-worker-node.js" (first (:args @captured))))
|
||||
(is (some #{"--repo"} (:args @captured)))
|
||||
(is (some #{"--root-dir"} (:args @captured)))
|
||||
(is (some #{"--server-list-file"} (:args @captured)))
|
||||
(is (some #{"/tmp/server-list"} (:args @captured)))
|
||||
(is (not-any? #{"--server-list-file"} (:args @captured)))
|
||||
(is (not-any? #{"/tmp/server-list"} (:args @captured)))
|
||||
(is (not-any? #{"--host" "--port"} (:args @captured)))
|
||||
(is (= true (get-in @captured [:opts :detached])))
|
||||
(is (= "1" (get-in @captured [:opts :env :ELECTRON_RUN_AS_NODE])))
|
||||
|
||||
12
src/test/logseq/db_worker/server_list_test.cljs
Normal file
12
src/test/logseq/db_worker/server_list_test.cljs
Normal file
@@ -0,0 +1,12 @@
|
||||
(ns logseq.db-worker.server-list-test
|
||||
(:require [cljs.test :refer [deftest is]]
|
||||
[logseq.db-worker.server-list :as server-list]))
|
||||
|
||||
(deftest path-derives-server-list-from-root-dir
|
||||
(is (= "/tmp/logseq-root/server-list"
|
||||
(server-list/path "/tmp/logseq-root"))))
|
||||
|
||||
(deftest path-rejects-missing-root-dir
|
||||
(is (thrown-with-msg? js/Error
|
||||
#"root-dir is required"
|
||||
(server-list/path nil))))
|
||||
Reference in New Issue
Block a user