Implement possibility for async command handlers (#1857)
* Implement possibility for async command handlers Command handler can now return results asynchronously, and those results as saved and persisted, indexed by command message-id. * Address feedback raised in PR comments * Different handler codes + simplified error message
This commit is contained in:
parent
0fa863d366
commit
b889a07a86
|
@ -352,11 +352,26 @@ function handleSend(params, context) {
|
|||
gasPrice: calculateGasPrice(params["bot-db"]["sliderValue"])
|
||||
};
|
||||
|
||||
try {
|
||||
return web3.eth.sendTransaction(data);
|
||||
} catch (err) {
|
||||
return {error: err.message};
|
||||
}
|
||||
|
||||
web3.eth.sendTransaction(data, function(error, hash) {
|
||||
if (error) {
|
||||
status.sendSignal("handler-data", {
|
||||
status: "failed",
|
||||
messageId: context["message-id"],
|
||||
error: error
|
||||
});
|
||||
} else {
|
||||
status.sendSignal("handler-data", {
|
||||
status: "sent",
|
||||
messageId: context["message-id"],
|
||||
hash: hash
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
status: 'not-confirmed'
|
||||
};
|
||||
}
|
||||
|
||||
function previewSend(params, context) {
|
||||
|
@ -435,6 +450,36 @@ function previewSend(params, context) {
|
|||
markup = [firstRow];
|
||||
}
|
||||
|
||||
if (!(context["handler-data"]
|
||||
&& context["handler-data"]["status"] === "sent")) {
|
||||
var pendingRow = status.components.text(
|
||||
{
|
||||
style: {
|
||||
color: "#9199a0",
|
||||
fontSize: 12,
|
||||
lineHeight: 18
|
||||
}
|
||||
},
|
||||
I18n.t('send_transaction_pending')
|
||||
);
|
||||
markup.push(pendingRow);
|
||||
}
|
||||
|
||||
if (context["handler-data"]
|
||||
&& context["handler-data"]["status"] === "failed") {
|
||||
var errorRow = status.components.text(
|
||||
{
|
||||
style: {
|
||||
color: "red",
|
||||
fontSize: 12,
|
||||
lineHeight: 18
|
||||
}
|
||||
},
|
||||
I18n.t('send_transaction_failed')
|
||||
);
|
||||
markup.push(errorRow);
|
||||
}
|
||||
|
||||
return {
|
||||
markup: status.components.view(
|
||||
{
|
||||
|
|
|
@ -14,6 +14,8 @@ I18n.translations = {
|
|||
send_explanation_3: 'probably within 30 seconds.',
|
||||
send_explanation_4: 'probably within a few seconds.',
|
||||
send_sending_to: 'to ',
|
||||
send_transaction_pending: 'transaction pending',
|
||||
send_transaction_failed: 'transaction failed',
|
||||
|
||||
eth: 'ETH',
|
||||
|
||||
|
|
|
@ -13,13 +13,14 @@
|
|||
|
||||
(defn generate-context
|
||||
"Generates context for jail call"
|
||||
[{:keys [chats] :accounts/keys [current-account-id]} chat-id to group-id]
|
||||
(merge {:platform platform/platform
|
||||
:from current-account-id
|
||||
:to to
|
||||
:chat {:chat-id chat-id
|
||||
:group-chat (or (get-in chats [chat-id :group-chat])
|
||||
(not (nil? group-id)))}}
|
||||
[{:keys [chats handler-data] :accounts/keys [current-account-id]} message-id chat-id to group-id]
|
||||
(merge {:platform platform/platform
|
||||
:from current-account-id
|
||||
:to to
|
||||
:chat {:chat-id chat-id
|
||||
:group-chat (or (get-in chats [chat-id :group-chat])
|
||||
(not (nil? group-id)))}
|
||||
:handler-data (get handler-data message-id)}
|
||||
i18n/delimeters))
|
||||
|
||||
;;;; Coeffects
|
||||
|
@ -69,7 +70,7 @@
|
|||
[trim-v]
|
||||
(fn [{:keys [db]}
|
||||
[{{:keys [command content-command params type]} :content
|
||||
:keys [chat-id jail-id group-id] :as message}
|
||||
:keys [chat-id jail-id group-id message-id] :as message}
|
||||
data-type]]
|
||||
(let [{:keys [chats]
|
||||
:accounts/keys [current-account-id]
|
||||
|
@ -84,7 +85,7 @@
|
|||
data-type]
|
||||
to (get-in contacts [chat-id :address])
|
||||
jail-params {:parameters params
|
||||
:context (generate-context db chat-id to group-id)}]
|
||||
:context (generate-context db message-id chat-id to group-id)}]
|
||||
{:chat-fx/call-jail {:jail-id jail-id
|
||||
:path path
|
||||
:params jail-params
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
[status-im.data-store.chats :as chats]
|
||||
[status-im.data-store.contacts :as contacts]
|
||||
[status-im.data-store.messages :as messages]
|
||||
[status-im.data-store.handler-data :as handler-data]
|
||||
[status-im.data-store.pending-messages :as pending-messages]
|
||||
[status-im.constants :refer [text-content-type
|
||||
content-type-command
|
||||
|
@ -219,6 +220,7 @@
|
|||
|
||||
(-> db
|
||||
(assoc :chats chats')
|
||||
(assoc :handler-data (handler-data/get-all))
|
||||
(dissoc :loaded-chats)
|
||||
(init-console-chat true))))
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
(:require [status-im.utils.handlers :refer [register-handler] :as u]
|
||||
[clojure.string :as s]
|
||||
[status-im.data-store.messages :as messages]
|
||||
[status-im.data-store.handler-data :as handler-data]
|
||||
[status-im.native-module.core :as status]
|
||||
[status-im.utils.random :as random]
|
||||
[status-im.utils.datetime :as time]
|
||||
|
@ -105,9 +106,20 @@
|
|||
params' (assoc params :command content')]
|
||||
(dispatch [:prepare-command! wallet-chat-id params'])))))))
|
||||
|
||||
(register-handler ::check-preview-refetch
|
||||
(fn [db [_ chat-id {:keys [message-id] :as message}]]
|
||||
(let [handler-data (get-in db [:handler-data message-id])]
|
||||
(if (:fetch-preview handler-data)
|
||||
(do (dispatch [:request-command-data (assoc message :jail-id chat-id) :preview])
|
||||
(handler-data/save-data {:message-id message-id
|
||||
:data (dissoc handler-data :fetch-preview)})
|
||||
(update-in db [:handler-data message-id] dissoc :fetch-preview))
|
||||
db))))
|
||||
|
||||
(register-handler ::send-command!
|
||||
(u/side-effect!
|
||||
(fn [_ [_ add-to-chat-id params hidden-params]]
|
||||
(dispatch [::check-preview-refetch add-to-chat-id (:command params)])
|
||||
(dispatch [::add-command add-to-chat-id params])
|
||||
(dispatch [::save-command! add-to-chat-id params hidden-params])
|
||||
(when (not= add-to-chat-id wallet-chat-id)
|
||||
|
@ -150,7 +162,7 @@
|
|||
to (get-in contacts [chat-id :address])
|
||||
identity (or owner-id bot chat-id)
|
||||
bot-db (get bot-db (or bot chat-id))
|
||||
params {:parameters params
|
||||
jail-params {:parameters params
|
||||
:context {:from address
|
||||
:to to
|
||||
:current-account (get accounts current-account-id)
|
||||
|
@ -161,7 +173,7 @@
|
|||
#(status/call-jail
|
||||
{:jail-id identity
|
||||
:path [handler-type name :handler]
|
||||
:params params
|
||||
:params jail-params
|
||||
:callback (fn [res]
|
||||
(dispatch [:command-handler! chat-id orig-params res]))})])))))
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
(s/def :chat/expandable-view-height-to-value (s/nilable number?))
|
||||
(s/def :chat/global-commands (s/nilable map?)) ; {key (keyword) command (map)} atm used for browse command
|
||||
(s/def :chat/loading-allowed (s/nilable boolean?)) ;;allow to load more messages
|
||||
(s/def :chat/handler-data (s/nilable map?))
|
||||
(s/def :chat/message-data (s/nilable map?))
|
||||
(s/def :chat/message-id->transaction-id (s/nilable map?))
|
||||
(s/def :chat/message-status (s/nilable map?))
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
(ns status-im.commands.events.jail
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.utils.handlers :as handlers]
|
||||
[status-im.data-store.handler-data :as handler-data]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:save-handler-data
|
||||
(fn [data]
|
||||
(handler-data/save-data data)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:set-handler-data
|
||||
[re-frame/trim-v]
|
||||
(fn [{:keys [db]} [chat-id {:keys [messageId] :as data}]]
|
||||
(let [;; this is very bad, we should refactor our db ASAP
|
||||
message (->> (get-in db [:chats chat-id :messages])
|
||||
(filter #(= (:message-id %) messageId))
|
||||
first)
|
||||
handler-data (cond-> (dissoc data :messageId)
|
||||
;; message not there yet, indicate we want to re-fetch preview once it lands there
|
||||
(nil? message)
|
||||
(assoc :fetch-preview true))
|
||||
old-handler-data (get-in db [:handler-data messageId] {})
|
||||
new-handler-data (merge old-handler-data handler-data)]
|
||||
(cond-> {:db (assoc-in db [:handler-data messageId] new-handler-data)
|
||||
:save-handler-data {:message-id messageId
|
||||
:data new-handler-data}}
|
||||
;; message was already added to db, we can re-fetch preview
|
||||
(not (nil? message))
|
||||
(assoc :dispatch [:request-command-data (assoc message :jail-id chat-id) :preview])))))
|
|
@ -10,7 +10,8 @@
|
|||
[status-im.constants :refer [console-chat-id]]
|
||||
[status-im.i18n :refer [get-contact-translated]]
|
||||
[taoensso.timbre :as log]
|
||||
[status-im.data-store.local-storage :as local-storage]))
|
||||
[status-im.data-store.local-storage :as local-storage]
|
||||
status-im.commands.events.jail))
|
||||
|
||||
(defn command-handler!
|
||||
[_ [chat-id
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
(ns status-im.data-store.handler-data
|
||||
(:require [cljs.reader :as reader]
|
||||
[status-im.data-store.realm.handler-data :as data-store]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(defn get-all []
|
||||
(->> (data-store/get-all-as-list)
|
||||
(map (fn [{:keys [message-id data]}]
|
||||
[message-id (reader/read-string data)]))
|
||||
(into {})))
|
||||
|
||||
(defn get-data [message-id]
|
||||
(-> message-id data-store/get-by-message-id :data reader/read-string))
|
||||
|
||||
(defn save-data [handler-data]
|
||||
(data-store/save (update handler-data :data pr-str)))
|
|
@ -0,0 +1,16 @@
|
|||
(ns status-im.data-store.realm.handler-data
|
||||
(:require [status-im.data-store.realm.core :as realm]))
|
||||
|
||||
(defn get-all []
|
||||
(realm/get-all @realm/account-realm :handler-data))
|
||||
|
||||
(defn get-all-as-list []
|
||||
(realm/realm-collection->list (get-all)))
|
||||
|
||||
(defn get-by-message-id
|
||||
[message-id]
|
||||
(realm/get-one-by-field-clj @realm/account-realm :handler-data :message-id message-id))
|
||||
|
||||
(defn save
|
||||
[handler-data]
|
||||
(realm/save @realm/account-realm :handler-data handler-data true))
|
|
@ -11,7 +11,7 @@
|
|||
[status-im.data-store.realm.schemas.account.v10.core :as v10]
|
||||
[status-im.data-store.realm.schemas.account.v11.core :as v11]
|
||||
[status-im.data-store.realm.schemas.account.v12.core :as v12]
|
||||
))
|
||||
[status-im.data-store.realm.schemas.account.v13.core :as v13]))
|
||||
|
||||
;; put schemas ordered by version
|
||||
(def schemas [{:schema v1/schema
|
||||
|
@ -49,4 +49,7 @@
|
|||
:migration v11/migration}
|
||||
{:schema v12/schema
|
||||
:schemaVersion 12
|
||||
:migration v12/migration}])
|
||||
:migration v12/migration}
|
||||
{:schema v13/schema
|
||||
:schemaVersion 13
|
||||
:migration v13/migration}])
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
(ns status-im.data-store.realm.schemas.account.v13.core
|
||||
(:require [status-im.data-store.realm.schemas.account.v11.chat :as chat]
|
||||
[status-im.data-store.realm.schemas.account.v1.chat-contact :as chat-contact]
|
||||
[status-im.data-store.realm.schemas.account.v6.command :as command]
|
||||
[status-im.data-store.realm.schemas.account.v9.command-parameter :as command-parameter]
|
||||
[status-im.data-store.realm.schemas.account.v7.contact :as contact]
|
||||
[status-im.data-store.realm.schemas.account.v1.discover :as discover]
|
||||
[status-im.data-store.realm.schemas.account.v1.kv-store :as kv-store]
|
||||
[status-im.data-store.realm.schemas.account.v10.message :as message]
|
||||
[status-im.data-store.realm.schemas.account.v12.pending-message :as pending-message]
|
||||
[status-im.data-store.realm.schemas.account.v1.processed-message :as processed-message]
|
||||
[status-im.data-store.realm.schemas.account.v1.request :as request]
|
||||
[status-im.data-store.realm.schemas.account.v1.tag :as tag]
|
||||
[status-im.data-store.realm.schemas.account.v1.user-status :as user-status]
|
||||
[status-im.data-store.realm.schemas.account.v5.contact-group :as contact-group]
|
||||
[status-im.data-store.realm.schemas.account.v5.group-contact :as group-contact]
|
||||
[status-im.data-store.realm.schemas.account.v8.local-storage :as local-storage]
|
||||
[status-im.data-store.realm.schemas.account.v13.handler-data :as handler-data]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(def schema [chat/schema
|
||||
chat-contact/schema
|
||||
command/schema
|
||||
command-parameter/schema
|
||||
contact/schema
|
||||
discover/schema
|
||||
kv-store/schema
|
||||
message/schema
|
||||
pending-message/schema
|
||||
processed-message/schema
|
||||
request/schema
|
||||
tag/schema
|
||||
user-status/schema
|
||||
contact-group/schema
|
||||
group-contact/schema
|
||||
local-storage/schema
|
||||
handler-data/schema])
|
||||
|
||||
(defn migration [old-realm new-realm]
|
||||
(log/debug "migrating v13 account database: " old-realm new-realm))
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
(ns status-im.data-store.realm.schemas.account.v13.handler-data)
|
||||
|
||||
(def schema {:name :handler-data
|
||||
:primaryKey :message-id
|
||||
:properties {:message-id "string"
|
||||
:data {:type "string"
|
||||
:default "{}"}}})
|
|
@ -152,6 +152,7 @@
|
|||
:chat/public-group-topic
|
||||
:chat/confirmation-code-sms-listener
|
||||
:chat/messages
|
||||
:chat/handler-data
|
||||
:chat/loaded-chats
|
||||
:chat/bot-subscriptions
|
||||
:chat/new-request
|
||||
|
|
|
@ -219,7 +219,7 @@
|
|||
:markup data}])
|
||||
"send-message" (dispatch [:send-message-from-jail {:chat-id chat_id
|
||||
:message data}])
|
||||
|
||||
"handler-data" (dispatch [:set-handler-data chat_id data])
|
||||
(log/debug "Unknown jail signal " type))))
|
||||
|
||||
(register-handler-fx
|
||||
|
|
Loading…
Reference in New Issue