浏览代码

enhance(rtc): try to restart-rtc when network-online event emits

rcmerci 6 月之前
父节点
当前提交
048bd106f6

+ 6 - 0
src/main/frontend/common/missionary.cljs

@@ -108,6 +108,12 @@
     (let [x (m/?> (m/relieve {} >in))]
       (m/amb x (do (m/? (m/sleep dur-ms)) (m/amb))))))
 
+(defn snapshot-of-flow
+  "Return a task. take first value from f.
+  can be understood as `deref` in missionary"
+  [f]
+  (m/reduce {} nil (m/eduction (take 1) f)))
+
 (defn- fail-case-default-handler
   [e]
   (when-not (instance? Cancelled e)

+ 6 - 0
src/main/frontend/flows.cljs

@@ -19,6 +19,8 @@
 (def ^:private current-login-user-validator (ma/validator current-login-user-schema))
 (def *current-login-user (atom nil :validator current-login-user-validator))
 
+(def *network-online? (atom nil))
+
 ;; Public Flows
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
@@ -42,3 +44,7 @@
             (fn dtor [] (.removeEventListener ^js js/document "visibilitychange" callback-fn)))))
        (m/eduction (dedupe))
        (m/relieve)))
+
+(def network-online-event-flow
+  (->> (m/watch *network-online?)
+       (m/eduction (filter true?))))

+ 24 - 3
src/main/frontend/handler/db_based/rtc_flows.cljs

@@ -98,7 +98,7 @@ conditions:
     (let [visibility (m/?< flows/document-visibility-state-flow)]
       (try
         (if (= "visible" visibility)
-          (let [rtc-lock (:rtc-lock (m/? (m/reduce {} nil (m/eduction (take 1) rtc-state-flow))))]
+          (let [rtc-lock (:rtc-lock (m/? (c.m/snapshot-of-flow rtc-state-flow)))]
             (if (not rtc-lock)
               :document-visible&rtc-not-running
               (m/amb)))
@@ -106,20 +106,41 @@ conditions:
         (catch Cancelled _
           (m/amb))))))
 
+(def ^:private network-online&rtc-not-running-flow
+  (m/ap
+    (let [online? (m/?< flows/network-online-event-flow)]
+      (try
+        (if online?
+          (let [rtc-lock (:rtc-lock (m/? (c.m/snapshot-of-flow rtc-state-flow)))]
+            (if (not rtc-lock)
+              :network-online&rtc-not-running
+              (m/amb)))
+          (m/amb))
+        (catch Cancelled _
+          (m/amb))))))
+
 (def trigger-start-rtc-flow
   (->>
-   [(m/eduction
+   [;; login-user changed
+    (m/eduction
      (keep (fn [user] (when (:email user) [:login])))
      flows/current-login-user-flow)
+    ;; repo changed
     (m/eduction
      (keep (fn [repo] (when repo [:graph-switch repo])))
      flows/current-repo-flow)
+    ;; trigger-rtc by somewhere else
     (m/eduction
      (keep (fn [repo] (when repo [:trigger-rtc repo])))
      (m/watch *rtc-start-trigger))
+    ;; document visibilitychange->true
+    (m/eduction
+     (map vector)
+     document-visible&rtc-not-running-flow)
+    ;; network online->true
     (m/eduction
      (map vector)
-     document-visible&rtc-not-running-flow)]
+     network-online&rtc-not-running-flow)]
    (apply c.m/mix)
    (m/eduction (filter (fn [_] (some? (state/get-auth-id-token)))))
    (c.m/debounce 200)))

+ 6 - 1
src/main/frontend/state.cljs

@@ -73,6 +73,7 @@
       :nfs/refreshing?                       nil
       :instrument/disabled?                  (storage/get "instrument-disabled")
       ;; TODO: how to detect the network reliably?
+      ;; NOTE: prefer to use flows/network-online-event-flow
       :network/online?         true
       :indexeddb/support?      true
       :me                      nil
@@ -1638,7 +1639,11 @@ Similar to re-frame subscriptions"
 
 (defn set-online!
   [value]
-  (set-state! :network/online? value))
+  (set-state! :network/online? value)
+  ;; to avoid watch whole big state atom,
+  ;; there's an atom flows/*network-online?,
+  ;; then we can use flows/network-online-event-flow
+  (reset! flows/*network-online? value))
 
 (defn get-plugins-slash-commands
   []

+ 1 - 3
src/main/frontend/worker/flows.cljs

@@ -5,9 +5,7 @@
 
 (def online-event-flow
   (->> (m/watch (get @worker-state/*state :thread-atom/online-event))
-       (m/eduction
-        (drop-while nil?)
-        (filter true?))))
+       (m/eduction (filter true?))))
 
 (comment
   ((m/reduce (fn [_ x] (prn :xxx x)) online-event-flow) prn prn))