Handle when message confirmations arrive out of order.

In some cases message confirmations might arrive out of order, before
status-go calls the callback for a sent message.

This commit changes the behavior so that confirmations out of order are
not ignored and they are checked when the callback for sending message
is called.

Signed-off-by: Andrea Maria Piana <andrea.maria.piana@gmail.com>
This commit is contained in:
Andrea Maria Piana 2020-04-22 14:27:47 +02:00
parent f170512e8f
commit 74f1405829
No known key found for this signature in database
GPG Key ID: AA6CCA6DE0E06424
3 changed files with 47 additions and 36 deletions

View File

@ -813,15 +813,12 @@
(handlers/register-handler-fx (handlers/register-handler-fx
:transport/message-sent :transport/message-sent
(fn [cofx [_ response messages-count]] (fn [cofx [_ response messages-count]]
(let [{:keys [localChatId id messageType]} (-> response :messages first)] (let [set-hash-fxs (map (fn [{:keys [localChatId id messageType]}]
(fx/merge cofx (transport.message/set-message-envelope-hash localChatId id messageType messages-count))
(handle-update response) (:messages response))]
(transport.message/set-message-envelope-hash localChatId id messageType messages-count))))) (apply fx/merge cofx
(conj set-hash-fxs
(handlers/register-handler-fx (handle-update response))))))
:transport/contact-message-sent
(fn [cofx [_ chat-id envelope-hash]]
(transport.message/set-contact-message-envelope-hash cofx chat-id envelope-hash)))
(handlers/register-handler-fx (handlers/register-handler-fx
:transport.callback/node-info-fetched :transport.callback/node-info-fetched

View File

@ -95,37 +95,37 @@
confirmations)})))) confirmations)}))))
(fx/defn update-envelope-status (fx/defn update-envelope-status
[{:keys [db] :as cofx} envelope-hash status] [{:keys [db] :as cofx} message-id status]
(let [{:keys [chat-id message-type message-id]} (if-let [{:keys [chat-id]}
(get-in db [:transport/message-envelopes envelope-hash])] (get-in db [:transport/message-envelopes message-id])]
(case message-type (when-let [{:keys [from]} (get-in db [:chats chat-id :messages message-id])]
:contact-message (check-confirmations cofx status chat-id message-id))
(when (= :sent status) ;; We don't have a message-envelope for this, might be that the confirmation
(remove-hash cofx envelope-hash)) ;; came too early
{:db (update-in db [:transport/message-confirmations message-id] conj status)}))
(when-let [{:keys [from]} (get-in db [:chats chat-id :messages message-id])]
(check-confirmations cofx status chat-id message-id)))))
(fx/defn update-envelopes-status (fx/defn update-envelopes-status
[{:keys [db] :as cofx} envelope-hashes status] [{:keys [db] :as cofx} message-id status]
(apply fx/merge cofx (map #(update-envelope-status % status) envelope-hashes))) (apply fx/merge cofx (map #(update-envelope-status % status) message-id)))
(fx/defn set-contact-message-envelope-hash
[{:keys [db] :as cofx} chat-id envelope-hash]
{:db (assoc-in db [:transport/message-envelopes envelope-hash]
{:chat-id chat-id
:message-type :contact-message})})
(fx/defn set-message-envelope-hash (fx/defn set-message-envelope-hash
"message-type is used for tracking" "message-type is used for tracking"
[{:keys [db] :as cofx} chat-id message-id message-type messages-count] [{:keys [db] :as cofx} chat-id message-id message-type messages-count]
{:db (-> db ;; Check first if the confirmation has already arrived
(assoc-in [:transport/message-envelopes message-id] (let [statuses (get-in db [:transport/message-confirmations message-id])
{:chat-id chat-id check-confirmations-fx (map
:message-id message-id #(check-confirmations % chat-id message-id)
:message-type message-type}) statuses)
(update-in [:transport/message-ids->confirmations message-id]
#(or % {:pending-confirmations messages-count})))}) add-envelope-data (fn [{:keys [db]}]
{:db (-> db
(update :transport/message-confirmations dissoc message-id)
(assoc-in [:transport/message-envelopes message-id]
{:chat-id chat-id
:message-type message-type})
(update-in [:transport/message-ids->confirmations message-id]
#(or % {:pending-confirmations messages-count})))})]
(apply fx/merge cofx (conj check-confirmations-fx add-envelope-data))))
(defn- own-info [db] (defn- own-info [db]
(let [{:keys [name photo-path address]} (:multiaccount db)] (let [{:keys [name photo-path address]} (:multiaccount db)]

View File

@ -67,7 +67,6 @@
(let [cofx (message/set-message-envelope-hash initial-cofx chat-id message-id :message-type 1)] (let [cofx (message/set-message-envelope-hash initial-cofx chat-id message-id :message-type 1)]
(testing "it sets the message-infos" (testing "it sets the message-infos"
(is (= {:chat-id chat-id (is (= {:chat-id chat-id
:message-id message-id
:message-type :message-type} :message-type :message-type}
(get-in cofx [:db :transport/message-envelopes message-id])))) (get-in cofx [:db :transport/message-envelopes message-id]))))
(testing "the message is sent" (testing "the message is sent"
@ -75,7 +74,6 @@
(get-in (get-in
(message/update-envelope-status cofx message-id :sent) (message/update-envelope-status cofx message-id :sent)
[:db :chats chat-id :messages message-id :outgoing-status])))) [:db :chats chat-id :messages message-id :outgoing-status]))))
(testing "the message is not sent" (testing "the message is not sent"
(is (= :not-sent (is (= :not-sent
(get-in (get-in
@ -107,6 +105,22 @@
(get-in (get-in
cofx cofx
[:db :chats chat-id :messages message-id :outgoing-status])))))) [:db :chats chat-id :messages message-id :outgoing-status]))))))
(testing "order of events is reversed"
(let [cofx (fx/merge
initial-cofx
(message/update-envelope-status message-id :sent)
(message/update-envelope-status message-id :sent)
(message/update-envelope-status message-id :sent)
(message/set-message-envelope-hash chat-id message-id :message-type 3))]
(testing "it removes the confirmations"
(is (not (get-in cofx [:db :transport/message-confirmations message-id])))
(is (not (get-in cofx [:db :transport/message-ids->confirmations message-id]))))
(testing "the message is sent"
(is (= :sent
(get-in
cofx
[:db :chats chat-id :messages message-id :outgoing-status]))))))
(testing "message not sent" (testing "message not sent"
(let [cofx (fx/merge (let [cofx (fx/merge
initial-cofx initial-cofx