[fix #5599] add semaphore for recurring events
:sync-wallet-transaction and :sync-state are self firing events that dispatch themselves later. this commit introduces semaphores to prevent these event-loops from starting multiple times when the user logs out and logs in again. Signed-off-by: Eric Dvorsak <eric@dvorsak.fr>
This commit is contained in:
parent
d46eec0bc8
commit
c5b17ac637
|
@ -4,6 +4,7 @@
|
|||
[status-im.utils.ethereum.tokens :as tokens]
|
||||
[status-im.utils.ethereum.core :as ethereum]
|
||||
[status-im.utils.handlers-macro :as handlers-macro]
|
||||
[status-im.utils.semaphores :as semaphores]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(def sync-interval-ms 15000)
|
||||
|
@ -88,12 +89,11 @@
|
|||
(< sync-interval-ms
|
||||
(- (time/timestamp) last-updated-at)))))
|
||||
|
||||
(defn set-sync-started [{:keys [db]}]
|
||||
{:db (assoc-in db [:wallet :transactions-sync-started?] true)})
|
||||
|
||||
; Fetch updated data for any unconfirmed transactions or incoming chat transactions missing in wallet
|
||||
; and schedule new recurring sync request
|
||||
(defn sync [{:keys [db] :as cofx}]
|
||||
(defn sync
|
||||
"Fetch updated data for any unconfirmed transactions or incoming chat transactions missing in wallet
|
||||
and schedule new recurring sync request"
|
||||
[{:keys [db] :as cofx}]
|
||||
(if (:account/account db)
|
||||
(let [in-progress? (get-in db [:wallet :transactions-loading?])
|
||||
{:keys [app-state network-status]} db]
|
||||
(if (and (not= network-status :offline)
|
||||
|
@ -105,4 +105,12 @@
|
|||
(handlers-macro/merge-fx cofx
|
||||
(run-update)
|
||||
(schedule-sync))
|
||||
(schedule-sync cofx))))
|
||||
(schedule-sync cofx)))
|
||||
{:db (semaphores/free :sync-wallet-transactions? cofx)}))
|
||||
|
||||
(defn start-sync [cofx]
|
||||
(when-not (semaphores/locked? :sync-wallet-transactions? cofx)
|
||||
(handlers-macro/merge-fx cofx
|
||||
(load-missing-chat-transactions)
|
||||
(semaphores/lock :sync-wallet-transactions?)
|
||||
(sync))))
|
||||
|
|
|
@ -5,13 +5,13 @@
|
|||
[status-im.native-module.core :as status]
|
||||
[status-im.utils.utils :as utils]
|
||||
[status-im.utils.datetime :as datetime]
|
||||
[status-im.utils.ethereum.core :as ethereum-utils]
|
||||
[status-im.utils.handlers :as handlers]
|
||||
[status-im.utils.handlers-macro :as handlers-macro]
|
||||
[status-im.utils.web3-provider :as web3-provider]
|
||||
[status-im.transport.core :as transport]
|
||||
[status-im.transport.inbox :as transport.inbox]
|
||||
[status-im.utils.ethereum.core :as ethereum]))
|
||||
[status-im.utils.ethereum.core :as ethereum]
|
||||
[status-im.protocol.models :as models]))
|
||||
|
||||
;;;; COFX
|
||||
(re-frame/reg-cofx
|
||||
|
@ -71,35 +71,15 @@
|
|||
|
||||
(handlers/register-handler-db
|
||||
:update-sync-state
|
||||
(fn [{:keys [sync-state sync-data] :as db} [_ error sync]]
|
||||
(let [{:keys [highestBlock currentBlock] :as state}
|
||||
(js->clj sync :keywordize-keys true)
|
||||
syncing? (> (- highestBlock currentBlock) constants/blocks-per-hour)
|
||||
new-state (cond
|
||||
error :offline
|
||||
syncing? (if (= sync-state :done)
|
||||
:pending
|
||||
:in-progress)
|
||||
:else (if (or (= sync-state :done)
|
||||
(= sync-state :pending))
|
||||
:done
|
||||
:synced))]
|
||||
(cond-> db
|
||||
(when (and (not= sync-data state) (= :in-progress new-state)))
|
||||
(assoc :sync-data state)
|
||||
(when (not= sync-state new-state))
|
||||
(assoc :sync-state new-state)))))
|
||||
(fn [cofx [_ error sync]]
|
||||
(models/update-sync-state cofx error sync)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:check-sync
|
||||
(fn [{{:keys [web3]} :db} _]
|
||||
{::web3-get-syncing web3
|
||||
:dispatch-later [{:ms 10000 :dispatch [:check-sync]}]}))
|
||||
:check-sync-state
|
||||
(fn [cofx _]
|
||||
(models/check-sync-state cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:initialize-sync-listener
|
||||
(fn [{{:keys [sync-listening-started network account/account] :as db} :db} _]
|
||||
(when (and (not sync-listening-started)
|
||||
(not (ethereum-utils/network-with-upstream-rpc? (get-in account [:networks network]))))
|
||||
{:db (assoc db :sync-listening-started true)
|
||||
:dispatch [:check-sync]})))
|
||||
:start-check-sync-state
|
||||
(fn [cofx _]
|
||||
(models/start-check-sync-state cofx)))
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
(ns status-im.protocol.models
|
||||
(:require [status-im.constants :as constants]
|
||||
[status-im.utils.semaphores :as semaphores]
|
||||
[status-im.utils.ethereum.core :as ethereum]
|
||||
[status-im.utils.handlers-macro :as handlers-macro]))
|
||||
|
||||
(defn update-sync-state
|
||||
[{:keys [sync-state sync-data] :as db} error sync]
|
||||
(let [{:keys [highestBlock currentBlock] :as state}
|
||||
(js->clj sync :keywordize-keys true)
|
||||
syncing? (> (- highestBlock currentBlock) constants/blocks-per-hour)
|
||||
new-state (cond
|
||||
error :offline
|
||||
syncing? (if (= sync-state :done)
|
||||
:pending
|
||||
:in-progress)
|
||||
:else (if (or (= sync-state :done)
|
||||
(= sync-state :pending))
|
||||
:done
|
||||
:synced))]
|
||||
(cond-> db
|
||||
(and (not= sync-data state) (= :in-progress new-state))
|
||||
(assoc :sync-data state)
|
||||
(not= sync-state new-state)
|
||||
(assoc :sync-state new-state))))
|
||||
|
||||
(defn check-sync-state
|
||||
[{{:keys [web3] :as db} :db :as cofx}]
|
||||
(if (:account/account db)
|
||||
{::web3-get-syncing web3
|
||||
:dispatch-later [{:ms 10000 :dispatch [:check-sync-state]}]}
|
||||
(semaphores/free :check-sync-state? cofx)))
|
||||
|
||||
(defn start-check-sync-state
|
||||
[{{:keys [network account/account] :as db} :db :as cofx}]
|
||||
(when (and (not (semaphores/locked? :check-sync-state? cofx))
|
||||
(not (ethereum/network-with-upstream-rpc? (get-in account [:networks network]))))
|
||||
(handlers-macro/merge-fx cofx
|
||||
{:dispatch [:check-sync-state]}
|
||||
(semaphores/lock :check-sync-state?))))
|
|
@ -41,6 +41,7 @@
|
|||
:peers-count 0
|
||||
:peers-summary []
|
||||
:notifications {}
|
||||
:semaphores #{}
|
||||
:network constants/default-network
|
||||
:networks/networks constants/default-networks
|
||||
:inbox/wnodes constants/default-wnodes
|
||||
|
@ -84,7 +85,6 @@
|
|||
|
||||
;;;;NODE
|
||||
|
||||
(spec/def ::sync-listening-started (spec/nilable boolean?))
|
||||
(spec/def ::sync-state (spec/nilable #{:pending :in-progress :synced :done :offline}))
|
||||
(spec/def ::sync-data (spec/nilable map?))
|
||||
|
||||
|
@ -169,6 +169,8 @@
|
|||
; Shows that push notification used to start the application is processed
|
||||
(spec/def :push-notifications/initial? (spec/nilable boolean?))
|
||||
|
||||
(spec/def ::semaphores set?)
|
||||
|
||||
(spec/def ::db (allowed-keys
|
||||
:opt
|
||||
[:contacts/contacts
|
||||
|
@ -241,12 +243,12 @@
|
|||
::mailserver-status
|
||||
::peers-count
|
||||
::peers-summary
|
||||
::sync-listening-started
|
||||
::sync-state
|
||||
::sync-data
|
||||
::network
|
||||
::chain
|
||||
::app-state
|
||||
::semaphores
|
||||
:navigation/view-id
|
||||
:navigation/navigation-stack
|
||||
:navigation/prev-tab-view-id
|
||||
|
|
|
@ -298,7 +298,7 @@
|
|||
(fn [{:keys [accounts/accounts accounts/create contacts/contacts networks/networks
|
||||
network network-status peers-count peers-summary view-id navigation-stack
|
||||
status-module-initialized? status-node-started? device-UUID
|
||||
push-notifications/initial?]
|
||||
push-notifications/initial? semaphores]
|
||||
:or [network (get app-db :network)]} [_ address]]
|
||||
(let [console-contact (get contacts constants/console-chat-id)
|
||||
current-account (accounts address)
|
||||
|
@ -319,7 +319,8 @@
|
|||
:push-notifications/initial? initial?
|
||||
:peers-summary peers-summary
|
||||
:peers-count peers-count
|
||||
:device-UUID device-UUID)
|
||||
:device-UUID device-UUID
|
||||
:semaphores semaphores)
|
||||
console-contact
|
||||
(assoc :contacts/contacts {constants/console-chat-id console-contact})))))
|
||||
|
||||
|
@ -329,7 +330,7 @@
|
|||
{:dispatch-n (cond-> [[:initialize-account-db address]
|
||||
[:initialize-protocol address]
|
||||
[:fetch-web3-node-version]
|
||||
[:initialize-sync-listener]
|
||||
[:start-check-sync-state]
|
||||
[:load-contacts]
|
||||
[:initialize-chats]
|
||||
[:initialize-browsers]
|
||||
|
|
|
@ -273,8 +273,4 @@
|
|||
(handlers/register-handler-fx
|
||||
:start-wallet-transactions-sync
|
||||
(fn [cofx _]
|
||||
(when-not (get-in cofx [:db :wallet :transactions-sync-started?])
|
||||
(handlers-macro/merge-fx cofx
|
||||
(wallet.transactions/load-missing-chat-transactions)
|
||||
(wallet.transactions/sync)
|
||||
(wallet.transactions/set-sync-started)))))
|
||||
(wallet.transactions/start-sync cofx)))
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
(ns status-im.utils.semaphores)
|
||||
|
||||
(defn lock [semaphore {:keys [db]}]
|
||||
{:pre [(keyword? semaphore)]}
|
||||
{:db (update db :semaphores conj semaphore)})
|
||||
|
||||
(defn free [semaphore {:keys [db]}]
|
||||
{:pre [(keyword? semaphore)]}
|
||||
(update db :semaphores disj semaphore))
|
||||
|
||||
(defn locked? [semaphore cofx]
|
||||
{:pre [(keyword? semaphore)]}
|
||||
((get-in cofx [:db :semaphores]) semaphore))
|
Loading…
Reference in New Issue