rtc_flows.cljs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. (ns frontend.handler.db-based.rtc-flows
  2. "Flows related to RTC"
  3. (:require [frontend.common.missionary :as c.m]
  4. [frontend.flows :as flows]
  5. [frontend.state :as state]
  6. [logseq.common.util :as common-util]
  7. [missionary.core :as m])
  8. (:import [missionary Cancelled]))
  9. (def rtc-log-flow
  10. (m/watch (:rtc/log @state/state)))
  11. (def rtc-download-log-flow
  12. (m/eduction
  13. (filter #(keyword-identical? :rtc.log/download (:type %)))
  14. rtc-log-flow))
  15. (def rtc-upload-log-flow
  16. (m/eduction
  17. (filter #(keyword-identical? :rtc.log/upload (:type %)))
  18. rtc-log-flow))
  19. (def rtc-misc-log-flow
  20. (m/eduction
  21. (remove #(contains? #{:rtc.log/download :rtc.log/upload} (:type %)))
  22. rtc-log-flow))
  23. (def rtc-state-flow
  24. (m/watch (:rtc/state @state/state)))
  25. (def rtc-running-flow
  26. (m/eduction (map :rtc-lock) rtc-state-flow))
  27. (def rtc-online-users-flow
  28. (c.m/throttle
  29. 500
  30. (m/eduction
  31. (map (fn [m]
  32. (when (and (= :open (:ws-state (:rtc-state m)))
  33. (:rtc-lock m))
  34. (:online-users m))))
  35. (dedupe)
  36. rtc-state-flow)))
  37. (def ^:private network-online-change-flow
  38. (m/stream
  39. (m/relieve
  40. (m/observe
  41. (fn ctor [emit!]
  42. (let [origin-callback js/window.ononline]
  43. (set! js/window.ononline emit!)
  44. (emit! nil)
  45. (fn dtor []
  46. (set! js/window.ononline origin-callback))))))))
  47. (def rtc-try-restart-flow
  48. "emit an event when it's time to restart rtc loop.
  49. conditions:
  50. - user logged in
  51. - no rtc loop running now
  52. - last rtc stop-reason is websocket message timeout
  53. - current js/navigator.onLine=true
  54. - throttle 5000ms"
  55. (->> (m/latest
  56. (fn [rtc-state _ login-user]
  57. (assoc rtc-state :login-user login-user))
  58. rtc-state-flow
  59. (c.m/continue-flow network-online-change-flow)
  60. flows/current-login-user-flow)
  61. (m/eduction
  62. (keep (fn [m]
  63. (let [{:keys [rtc-lock last-stop-exception-ex-data graph-uuid login-user]} m]
  64. (when (and (some? (:email login-user))
  65. (some? graph-uuid)
  66. (not rtc-lock) ; no rtc loop now
  67. (= :rtc.exception/ws-timeout (:type last-stop-exception-ex-data))
  68. (true? js/navigator.onLine))
  69. {:graph-uuid graph-uuid :t (common-util/time-ms)})))))
  70. (c.m/throttle 5000)))
  71. (def logout-or-graph-switch-flow
  72. (c.m/mix
  73. (m/eduction
  74. (filter #(= :logout %))
  75. flows/current-login-user-flow)
  76. (m/eduction
  77. (keep (fn [repo] (when repo :graph-switch)))
  78. flows/current-repo-flow)))
  79. (def ^:private *rtc-start-trigger (atom nil))
  80. (defn trigger-rtc-start
  81. [repo]
  82. (assert (some? repo))
  83. (reset! *rtc-start-trigger repo))
  84. (def ^:private document-visible&rtc-not-running-flow
  85. (m/ap
  86. (let [visibility (m/?< flows/document-visibility-state-flow)]
  87. (try
  88. (if (= "visible" visibility)
  89. (let [rtc-lock (:rtc-lock (m/? (c.m/snapshot-of-flow rtc-state-flow)))]
  90. (if (not rtc-lock)
  91. :document-visible&rtc-not-running
  92. (m/amb)))
  93. (m/amb))
  94. (catch Cancelled _
  95. (m/amb))))))
  96. (def ^:private network-online&rtc-not-running-flow
  97. (m/ap
  98. (let [online? (m/?< flows/network-online-event-flow)]
  99. (try
  100. (if online?
  101. (let [rtc-lock (:rtc-lock (m/? (c.m/snapshot-of-flow rtc-state-flow)))]
  102. (if (not rtc-lock)
  103. :network-online&rtc-not-running
  104. (m/amb)))
  105. (m/amb))
  106. (catch Cancelled _
  107. (m/amb))))))
  108. (def trigger-start-rtc-flow
  109. (->>
  110. [;; login-user changed
  111. (m/eduction
  112. (keep (fn [user] (when (:email user) [:login])))
  113. flows/current-login-user-flow)
  114. ;; repo changed
  115. (m/eduction
  116. (keep (fn [repo] (when repo [:graph-switch repo])))
  117. flows/current-repo-flow)
  118. ;; trigger-rtc by somewhere else
  119. (m/eduction
  120. (keep (fn [repo] (when repo [:trigger-rtc repo])))
  121. (m/watch *rtc-start-trigger))
  122. ;; document visibilitychange->true
  123. (m/eduction
  124. (map vector)
  125. document-visible&rtc-not-running-flow)
  126. ;; network online->true
  127. (m/eduction
  128. (map vector)
  129. network-online&rtc-not-running-flow)]
  130. (apply c.m/mix)
  131. (m/eduction (filter (fn [_] (some? (state/get-auth-id-token)))))
  132. (c.m/debounce 200)))