Skip to content

Commit fa67d12

Browse files
authored
agent: fix deleting messages after delivery to avoid deleting shared message bodies (#1455)
* agent: fix deleting messages after delivery to avoid deleting shared message bodies * fix, comments * rename * comment
1 parent 55ff581 commit fa67d12

File tree

1 file changed

+34
-15
lines changed

1 file changed

+34
-15
lines changed

src/Simplex/Messaging/Agent/Store/AgentStore.hs

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,12 +1001,13 @@ deleteMsg db connId msgId =
10011001
DB.execute db "DELETE FROM messages WHERE conn_id = ? AND internal_id = ?;" (connId, msgId)
10021002

10031003
deleteMsgContent :: DB.Connection -> ConnId -> InternalId -> IO ()
1004-
deleteMsgContent db connId msgId =
1004+
deleteMsgContent db connId msgId = do
10051005
#if defined(dbPostgres)
10061006
DB.execute db "UPDATE messages SET msg_body = ''::BYTEA WHERE conn_id = ? AND internal_id = ?" (connId, msgId)
10071007
#else
10081008
DB.execute db "UPDATE messages SET msg_body = x'' WHERE conn_id = ? AND internal_id = ?" (connId, msgId)
10091009
#endif
1010+
DB.execute db "UPDATE snd_messages SET snd_message_body_id = NULL WHERE conn_id = ? AND internal_id = ?" (connId, msgId)
10101011

10111012
deleteDeliveredSndMsg :: DB.Connection -> ConnId -> InternalId -> IO ()
10121013
deleteDeliveredSndMsg db connId msgId = do
@@ -1019,21 +1020,39 @@ deleteSndMsgDelivery db connId SndQueue {dbQueueId} msgId keepForReceipt = do
10191020
db
10201021
"DELETE FROM snd_message_deliveries WHERE conn_id = ? AND snd_queue_id = ? AND internal_id = ?"
10211022
(connId, dbQueueId, msgId)
1022-
cnt <- countPendingSndDeliveries_ db connId msgId
1023-
when (cnt == 0) $ do
1024-
maybeFirstRow id (DB.query db "SELECT rcpt_internal_id, rcpt_status, snd_message_body_id FROM snd_messages WHERE conn_id = ? AND internal_id = ?" (connId, msgId)) >>= \case
1025-
Just (Just (_ :: Int64), Just MROk, sndMsgBodyId_) -> do
1026-
forM_ sndMsgBodyId_ deleteSndMsgBody
1027-
deleteMsg db connId msgId
1028-
Just (_, _, Just (sndMsgBodyId :: Int64)) -> do
1029-
deleteSndMsgBody sndMsgBodyId
1030-
delKeepForReceipt
1031-
_ ->
1032-
delKeepForReceipt
1023+
getRcptAndBodyId >>= mapM_ deleteMsgAndBody
10331024
where
1034-
delKeepForReceipt = if keepForReceipt then deleteMsgContent db connId msgId else deleteMsg db connId msgId
1035-
deleteSndMsgBody sndMsgBodyId =
1036-
DB.execute db "DELETE FROM snd_message_bodies WHERE snd_message_body_id = ?" (Only sndMsgBodyId)
1025+
getRcptAndBodyId :: IO (Maybe (Maybe MsgReceiptStatus, Maybe Int64))
1026+
getRcptAndBodyId =
1027+
-- Get receipt status and message body ID if there are no pending deliveries.
1028+
-- The current delivery is deleted above.
1029+
maybeFirstRow id $
1030+
DB.query
1031+
db
1032+
[sql|
1033+
SELECT rcpt_status, snd_message_body_id FROM snd_messages
1034+
WHERE NOT EXISTS (SELECT 1 FROM snd_message_deliveries WHERE conn_id = ? AND internal_id = ? AND failed = 0)
1035+
AND conn_id = ? AND internal_id = ?
1036+
|]
1037+
(connId, msgId, connId, msgId)
1038+
deleteMsgAndBody :: (Maybe MsgReceiptStatus, Maybe Int64) -> IO ()
1039+
deleteMsgAndBody (rcptStatus_, sndMsgBodyId_) = do
1040+
let del = case rcptStatus_ of
1041+
-- we are not deleting message if receipt is not received or had incorrect hash (for debugging).
1042+
Just MROk -> deleteMsg
1043+
_ -> if keepForReceipt then deleteMsgContent else deleteMsg
1044+
del db connId msgId
1045+
forM_ sndMsgBodyId_ $ \bodyId ->
1046+
-- Delete message body if it is not used by any snd message.
1047+
-- The current snd message is already deleted by deleteMsg or cleared by deleteMsgContent.
1048+
DB.execute
1049+
db
1050+
[sql|
1051+
DELETE FROM snd_message_bodies
1052+
WHERE NOT EXISTS (SELECT 1 FROM snd_messages WHERE snd_message_body_id = ?)
1053+
AND snd_message_body_id = ?
1054+
|]
1055+
(bodyId, bodyId)
10371056

10381057
countPendingSndDeliveries_ :: DB.Connection -> ConnId -> InternalId -> IO Int
10391058
countPendingSndDeliveries_ db connId msgId = do

0 commit comments

Comments
 (0)