Add a long running task to transfer events to Go when the user logs in, rename interceptors namespace to core, send events in batches, capture s/on-will-focus, capture navigate-to-cofx, stop long running task if any event fails validation, not quite ready yet, needs more testing
Remove redudant println, don't stop the task in case of a bad event, just reject that batch, capture navigate-to-cofx events with an effect, capture parts of screens/on-will-focus event Fix lint Shorten comment widths, update to use less brackets, call events reset once, double run safety for long running task Call onboard after stopping Reset periodic-tasks-chan to on close, formatting Get rid of redundant inline function Update go version to point to 0.75.1 Signed-off-by: Shivek Khurana <shivek@status.im>
This commit is contained in:
parent
93ce02b547
commit
ed4e227144
|
@ -74,6 +74,7 @@
|
||||||
[theme-switcher]
|
[theme-switcher]
|
||||||
[rn/view
|
[rn/view
|
||||||
(for [{:keys [name]} screens]
|
(for [{:keys [name]} screens]
|
||||||
|
^{:key name}
|
||||||
[rn/touchable-opacity {:on-press #(navigation/navigate-to name nil)}
|
[rn/touchable-opacity {:on-press #(navigation/navigate-to name nil)}
|
||||||
[rn/view {:style {:padding-vertical 8}}
|
[rn/view {:style {:padding-vertical 8}}
|
||||||
[quo/text (str "Preview " name)]]])]])
|
[quo/text (str "Preview " name)]]])]])
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
(ns status-im.anon-metrics.core
|
||||||
|
(:require [status-im.ethereum.json-rpc :as json-rpc]
|
||||||
|
[taoensso.timbre :as log]
|
||||||
|
[re-frame.core :as re-frame]
|
||||||
|
[re-frame.interceptor :refer [->interceptor]]
|
||||||
|
[status-im.utils.async :refer [async-periodic-exec async-periodic-stop!]]
|
||||||
|
[status-im.utils.platform :as platform]
|
||||||
|
[status-im.utils.build :as build]
|
||||||
|
[status-im.utils.fx :as fx]
|
||||||
|
[status-im.anon-metrics.transformers :as txf]))
|
||||||
|
|
||||||
|
(defonce events-foyer (atom []))
|
||||||
|
(defonce periodic-tasks-chan (atom nil))
|
||||||
|
|
||||||
|
(defn onboard-events
|
||||||
|
"Check if there are any events in the foyer,
|
||||||
|
flush them to the backend and clear foyer on-success."
|
||||||
|
[]
|
||||||
|
(let [outstanding-events @events-foyer]
|
||||||
|
(when (seq outstanding-events)
|
||||||
|
(reset! events-foyer [])
|
||||||
|
(json-rpc/call
|
||||||
|
{:method "appmetrics_saveAppMetrics"
|
||||||
|
:params [outstanding-events]
|
||||||
|
:on-success #()
|
||||||
|
:on-error (fn [err]
|
||||||
|
(log/error {:error err
|
||||||
|
:events outstanding-events})
|
||||||
|
(log/warn "All outstanding events will be rejected"))}))))
|
||||||
|
|
||||||
|
(re-frame/reg-fx
|
||||||
|
::transfer-data
|
||||||
|
(fn [transfer?]
|
||||||
|
(if (and transfer?
|
||||||
|
;; double run safety
|
||||||
|
(not @periodic-tasks-chan))
|
||||||
|
(do
|
||||||
|
(log/info "[anon-metrics] Start collection service")
|
||||||
|
(reset! periodic-tasks-chan
|
||||||
|
;; interval = 4000 ms (run every `interval` ms)
|
||||||
|
;; timeout = 5000 ms (exit if the fn doesn't exit within `timeout` ms)
|
||||||
|
(async-periodic-exec onboard-events 4000 5000)))
|
||||||
|
(do
|
||||||
|
(log/info "[anon-metrics] Stop collection service")
|
||||||
|
(async-periodic-stop! @periodic-tasks-chan)
|
||||||
|
(reset! periodic-tasks-chan nil)
|
||||||
|
|
||||||
|
;; final onboard, will save and clear any pending events
|
||||||
|
(onboard-events)))))
|
||||||
|
|
||||||
|
(fx/defn start-transferring
|
||||||
|
[_]
|
||||||
|
{::transfer-data true})
|
||||||
|
|
||||||
|
(fx/defn stop-transferring
|
||||||
|
[_]
|
||||||
|
{::transfer-data false})
|
||||||
|
|
||||||
|
(defn transform-and-log [context]
|
||||||
|
(when-let [transformed-payload (txf/transform context)]
|
||||||
|
(swap!
|
||||||
|
events-foyer
|
||||||
|
conj
|
||||||
|
{:event (-> context :coeffects :event first)
|
||||||
|
:value transformed-payload
|
||||||
|
:app_version build/version
|
||||||
|
:os platform/os})))
|
||||||
|
|
||||||
|
(defn catch-events-before [context]
|
||||||
|
(transform-and-log context)
|
||||||
|
context)
|
||||||
|
|
||||||
|
(def interceptor
|
||||||
|
(->interceptor
|
||||||
|
:id :catch-events
|
||||||
|
:before catch-events-before))
|
||||||
|
|
||||||
|
(re-frame/reg-fx ::transform-and-log transform-and-log)
|
||||||
|
|
||||||
|
(fx/defn hoax-capture-event
|
||||||
|
"Due to usage of fx/defn with fx/merge, it might not be able to
|
||||||
|
intercept some events (like navigate-to-cofx). In cases like that,
|
||||||
|
this hoax capture event can be used in conjunction with `fx/merge`"
|
||||||
|
{:events [::hoax-capture-event]}
|
||||||
|
[_ {:keys [og-event]}]
|
||||||
|
;; re-shape event to look like a context object
|
||||||
|
{::transform-and-log {:coeffects {:event og-event}}})
|
||||||
|
|
||||||
|
(comment
|
||||||
|
;; read the database
|
||||||
|
(def events-in-db (atom nil))
|
||||||
|
(->> events-in-db
|
||||||
|
deref
|
||||||
|
(take-last 5))
|
||||||
|
(json-rpc/call {:method "appmetrics_getAppMetrics"
|
||||||
|
:params [1000 0] ; limit, offset
|
||||||
|
:on-success #(reset! events-in-db %)}))
|
|
@ -1,27 +0,0 @@
|
||||||
(ns status-im.anon-metrics.interceptors
|
|
||||||
(:require [status-im.ethereum.json-rpc :as json-rpc]
|
|
||||||
[taoensso.timbre :as log]
|
|
||||||
[re-frame.interceptor :refer [->interceptor]]
|
|
||||||
[status-im.utils.platform :as platform]
|
|
||||||
[status-im.utils.build :as build]
|
|
||||||
[status-im.anon-metrics.transformers :as txf]))
|
|
||||||
|
|
||||||
(defn transform-and-log [context]
|
|
||||||
(log/info :catch-event-fn (get-in context [:coeffects :event]))
|
|
||||||
(when-let [transformed-payload (txf/transform context)]
|
|
||||||
(json-rpc/call {:method "appmetrics_saveAppMetrics"
|
|
||||||
:params [[{:event (-> context :coeffects :event first)
|
|
||||||
:value transformed-payload
|
|
||||||
:app_version build/version
|
|
||||||
:os platform/os}]]
|
|
||||||
:on-failure #(log/error)})))
|
|
||||||
|
|
||||||
(defn catch-events-before [context]
|
|
||||||
(log/info "catch-events/interceptor fired")
|
|
||||||
(transform-and-log context)
|
|
||||||
context)
|
|
||||||
|
|
||||||
(def catch-events
|
|
||||||
(->interceptor
|
|
||||||
:id :catch-events
|
|
||||||
:before catch-events-before))
|
|
|
@ -1,14 +1,24 @@
|
||||||
(ns status-im.anon-metrics.transformers)
|
(ns status-im.anon-metrics.transformers)
|
||||||
|
|
||||||
(defn navigate-to-txf [context]
|
(defn navigate-to-txf [context]
|
||||||
{:view-id (second context)
|
(let [event (-> context :coeffects :event)]
|
||||||
:params (-> context
|
{:view_id (second event)
|
||||||
(nth 2)
|
:params {:screen (get-in event [1 :screen] "")}}))
|
||||||
(select-keys [:screen]))})
|
|
||||||
|
|
||||||
(def transformations
|
(defn screens-on-will-focus-txf [context]
|
||||||
{:navigate-to navigate-to-txf})
|
(let [view-id (-> context :coeffects :event second)]
|
||||||
|
;; we need this check because in some cases, :screens/on-will-focus is dispatched
|
||||||
|
;; after navigate to this check ensures that only the events that are not handled
|
||||||
|
;; via navigate to are captured hence avoiding duplicates
|
||||||
|
(when (#{:chat :empty-tab :wallet :status :my-profile} view-id)
|
||||||
|
{:view_id view-id
|
||||||
|
:params {:screen ""}})))
|
||||||
|
|
||||||
|
(def value-transformations
|
||||||
|
{:navigate-to navigate-to-txf
|
||||||
|
:screens/on-will-focus screens-on-will-focus-txf})
|
||||||
|
|
||||||
(defn transform [ctx]
|
(defn transform [ctx]
|
||||||
(when-let [txf (-> ctx first transformations)]
|
(when-let [txf (-> ctx :coeffects :event first value-transformations)]
|
||||||
(txf ctx)))
|
(txf ctx)))
|
||||||
|
|
||||||
|
|
|
@ -185,7 +185,8 @@
|
||||||
"mailservers_addChatRequestRanges" {}
|
"mailservers_addChatRequestRanges" {}
|
||||||
"mailservers_getChatRequestRanges" {}
|
"mailservers_getChatRequestRanges" {}
|
||||||
"mailservers_deleteChatRequestRange" {}
|
"mailservers_deleteChatRequestRange" {}
|
||||||
"appmetrics_saveAppMetrics" {}})
|
"appmetrics_saveAppMetrics" {}
|
||||||
|
"appmetrics_getAppMetrics" {}})
|
||||||
|
|
||||||
(defn on-error-retry
|
(defn on-error-retry
|
||||||
[call-method {:keys [method number-of-retries delay on-error] :as arg}]
|
[call-method {:keys [method number-of-retries delay on-error] :as arg}]
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
[status-im.ui.components.permissions :as permissions]
|
[status-im.ui.components.permissions :as permissions]
|
||||||
[status-im.utils.utils :as utils]
|
[status-im.utils.utils :as utils]
|
||||||
[status-im.ethereum.json-rpc :as json-rpc]
|
[status-im.ethereum.json-rpc :as json-rpc]
|
||||||
|
[status-im.anon-metrics.core :as anon-metrics]
|
||||||
clojure.set
|
clojure.set
|
||||||
status-im.currency.core
|
status-im.currency.core
|
||||||
status-im.navigation
|
status-im.navigation
|
||||||
|
@ -185,7 +186,8 @@
|
||||||
(chat/preload-chat-data cofx constants/timeline-chat-id)))
|
(chat/preload-chat-data cofx constants/timeline-chat-id)))
|
||||||
|
|
||||||
(fx/defn on-will-focus
|
(fx/defn on-will-focus
|
||||||
{:events [:screens/on-will-focus]}
|
{:events [:screens/on-will-focus]
|
||||||
|
:interceptors [anon-metrics/interceptor]}
|
||||||
[cofx view-id]
|
[cofx view-id]
|
||||||
(fx/merge cofx
|
(fx/merge cofx
|
||||||
#(case view-id
|
#(case view-id
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
(ns status-im.multiaccounts.login.core
|
(ns status-im.multiaccounts.login.core
|
||||||
(:require [re-frame.core :as re-frame]
|
(:require [re-frame.core :as re-frame]
|
||||||
|
[status-im.anon-metrics.core :as anon-metrics]
|
||||||
[status-im.chat.models.loading :as chat.loading]
|
[status-im.chat.models.loading :as chat.loading]
|
||||||
[status-im.contact.core :as contact]
|
[status-im.contact.core :as contact]
|
||||||
[status-im.data-store.settings :as data-store.settings]
|
[status-im.data-store.settings :as data-store.settings]
|
||||||
|
@ -361,6 +362,8 @@
|
||||||
::json-rpc/call
|
::json-rpc/call
|
||||||
[{:method "web3_clientVersion"
|
[{:method "web3_clientVersion"
|
||||||
:on-success #(re-frame/dispatch [::initialize-web3-client-version %])}]}
|
:on-success #(re-frame/dispatch [::initialize-web3-client-version %])}]}
|
||||||
|
;; Start tasks to save usage data locally
|
||||||
|
(anon-metrics/start-transferring)
|
||||||
;;FIXME
|
;;FIXME
|
||||||
(when nodes
|
(when nodes
|
||||||
(fleet/set-nodes :eth.contract nodes))
|
(fleet/set-nodes :eth.contract nodes))
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
(ns status-im.multiaccounts.logout.core
|
(ns status-im.multiaccounts.logout.core
|
||||||
(:require [re-frame.core :as re-frame]
|
(:require [re-frame.core :as re-frame]
|
||||||
|
[status-im.anon-metrics.core :as anon-metrics]
|
||||||
[status-im.i18n.i18n :as i18n]
|
[status-im.i18n.i18n :as i18n]
|
||||||
[status-im.init.core :as init]
|
[status-im.init.core :as init]
|
||||||
[status-im.native-module.core :as status]
|
[status-im.native-module.core :as status]
|
||||||
|
@ -20,6 +21,7 @@
|
||||||
:keychain/clear-user-password key-uid
|
:keychain/clear-user-password key-uid
|
||||||
::init/open-multiaccounts #(re-frame/dispatch [::init/initialize-multiaccounts % {:logout? logout?}])}
|
::init/open-multiaccounts #(re-frame/dispatch [::init/initialize-multiaccounts % {:logout? logout?}])}
|
||||||
(notifications/logout-disable)
|
(notifications/logout-disable)
|
||||||
|
(anon-metrics/stop-transferring)
|
||||||
(keychain/save-auth-method key-uid auth-method)
|
(keychain/save-auth-method key-uid auth-method)
|
||||||
(transport/stop-whisper)
|
(transport/stop-whisper)
|
||||||
(wallet/clear-timeouts)
|
(wallet/clear-timeouts)
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
[status-im.ui.screens.routing.core :as navigation]
|
[status-im.ui.screens.routing.core :as navigation]
|
||||||
[taoensso.timbre :as log]
|
[taoensso.timbre :as log]
|
||||||
[status-im.utils.fx :as fx]
|
[status-im.utils.fx :as fx]
|
||||||
[status-im.anon-metrics.interceptors :as anon-metrics]))
|
[status-im.anon-metrics.core :as anon-metrics]))
|
||||||
|
|
||||||
(re-frame/reg-fx
|
(re-frame/reg-fx
|
||||||
::navigate-to
|
::navigate-to
|
||||||
|
@ -38,15 +38,16 @@
|
||||||
(assoc-in [:navigation/screen-params view] screen-params)))
|
(assoc-in [:navigation/screen-params view] screen-params)))
|
||||||
|
|
||||||
(fx/defn navigate-to-cofx
|
(fx/defn navigate-to-cofx
|
||||||
[{:keys [db]} go-to-view-id screen-params]
|
[{:keys [db] :as cofx} go-to-view-id screen-params]
|
||||||
{:db
|
{:db
|
||||||
(-> (assoc db :view-id go-to-view-id)
|
(-> (assoc db :view-id go-to-view-id)
|
||||||
(all-screens-params go-to-view-id screen-params))
|
(all-screens-params go-to-view-id screen-params))
|
||||||
::navigate-to [go-to-view-id screen-params]})
|
::navigate-to [go-to-view-id screen-params]
|
||||||
|
;; simulate a navigate-to event so it can be captured be anon-metrics
|
||||||
|
::anon-metrics/transform-and-log {:coeffects {:event [:navigate-to go-to-view-id screen-params]}}})
|
||||||
|
|
||||||
(fx/defn navigate-to
|
(fx/defn navigate-to
|
||||||
{:events [:navigate-to]
|
{:events [:navigate-to]}
|
||||||
:interceptors [anon-metrics/catch-events]}
|
|
||||||
[cofx go-to-view-id screen-params]
|
[cofx go-to-view-id screen-params]
|
||||||
(navigate-to-cofx cofx go-to-view-id screen-params))
|
(navigate-to-cofx cofx go-to-view-id screen-params))
|
||||||
|
|
||||||
|
@ -62,7 +63,7 @@
|
||||||
|
|
||||||
(fx/defn navigate-replace
|
(fx/defn navigate-replace
|
||||||
{:events [:navigate-replace]
|
{:events [:navigate-replace]
|
||||||
:interceptors [anon-metrics/catch-events]}
|
:interceptors [anon-metrics/interceptor]}
|
||||||
[{:keys [db]} go-to-view-id screen-params]
|
[{:keys [db]} go-to-view-id screen-params]
|
||||||
(let [db (cond-> (assoc db :view-id go-to-view-id)
|
(let [db (cond-> (assoc db :view-id go-to-view-id)
|
||||||
(seq screen-params)
|
(seq screen-params)
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
(recur acc (seq acc)))))))
|
(recur acc (seq acc)))))))
|
||||||
|
|
||||||
(defn task-queue
|
(defn task-queue
|
||||||
"Creates `core.async` channel which will process 0 arg functions put there in serial fashon.
|
"Creates `core.async` channel which will process 0 arg functions put there in serial fashion.
|
||||||
Takes the same argument/s as `core.async/chan`, those arguments will be delegated to the
|
Takes the same argument/s as `core.async/chan`, those arguments will be delegated to the
|
||||||
channel constructor.
|
channel constructor.
|
||||||
Returns task-queue where tasks represented by 0 arg task functions can be put for processing."
|
Returns task-queue where tasks represented by 0 arg task functions can be put for processing."
|
||||||
|
@ -100,3 +100,11 @@
|
||||||
(async/alts! [finished-chan (timeout timeout-ms)])
|
(async/alts! [finished-chan (timeout timeout-ms)])
|
||||||
(recur))))
|
(recur))))
|
||||||
do-now-chan))
|
do-now-chan))
|
||||||
|
|
||||||
|
(comment
|
||||||
|
(def c (atom nil))
|
||||||
|
|
||||||
|
(let [periodic-task-chan (async-periodic-exec #(prn :task) 5000 1000)]
|
||||||
|
(reset! c periodic-task-chan))
|
||||||
|
|
||||||
|
(async-periodic-stop! @c))
|
||||||
|
|
Loading…
Reference in New Issue