From 1a560b03334a21104029f5ff473e44f06fa020c0 Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Mon, 18 Aug 2025 12:44:47 +0400 Subject: [PATCH] don't do unnecessary ack --- src/Simplex/Chat/Library/Subscriber.hs | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/Simplex/Chat/Library/Subscriber.hs b/src/Simplex/Chat/Library/Subscriber.hs index f1e325d558..1ebf766969 100644 --- a/src/Simplex/Chat/Library/Subscriber.hs +++ b/src/Simplex/Chat/Library/Subscriber.hs @@ -469,7 +469,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage = CRContactUri _ -> throwChatError $ CECommandError "unexpected ConnectionRequestUri type" MSG msgMeta _msgFlags msgBody -> do tags <- newTVarIO [] - withAckMessage "contact msg" agentConnId msgMeta True (Just tags) $ \eInfo -> do + withAckMessage "contact msg" agentConnId msgMeta Nothing True (Just tags) $ \eInfo -> do let MsgMeta {pqEncryption} = msgMeta (ct', conn') <- updateContactPQRcv user ct conn pqEncryption checkIntegrityCreateItem (CDDirectRcv ct') msgMeta `catchChatError` \_ -> pure () @@ -893,7 +893,8 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage = _ -> messageWarning "sendXGrpMemCon: member category GCPreMember or GCPostMember is expected" MSG msgMeta _msgFlags msgBody -> do tags <- newTVarIO [] - withAckMessage "group msg" agentConnId msgMeta True (Just tags) $ \eInfo -> do + cancelAckVar <- newTVarIO False + withAckMessage "group msg" agentConnId msgMeta (Just cancelAckVar) True (Just tags) $ \eInfo -> do -- possible improvement is to choose scope based on event (some events specify scope) (gInfo', m', scopeInfo) <- mkGroupChatScope gInfo m checkIntegrityCreateItem (CDGroupRcv gInfo' scopeInfo m') msgMeta `catchChatError` \_ -> pure () @@ -902,7 +903,9 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage = unless (blockedByAdmin m) $ forM_ (M.assocs fwdScopesMsgs) $ \(groupForwardScope, fwdMsgs) -> forwardMsgs groupForwardScope (L.reverse fwdMsgs) `catchChatError` eToView - when shouldDelConns $ deleteGroupConnections gInfo' True + when shouldDelConns $ do + atomically $ writeTVar cancelAckVar True + deleteGroupConnections gInfo' True checkSendRcpt $ rights aChatMsgs where aChatMsgs = parseChatMessages msgBody @@ -1544,10 +1547,10 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage = withAckMessage' :: Text -> ConnId -> MsgMeta -> CM () -> CM () withAckMessage' label cId msgMeta action = do - withAckMessage label cId msgMeta False Nothing $ \_ -> action $> False + withAckMessage label cId msgMeta Nothing False Nothing $ \_ -> action $> False - withAckMessage :: Text -> ConnId -> MsgMeta -> Bool -> Maybe (TVar [Text]) -> (Text -> CM Bool) -> CM () - withAckMessage label cId msgMeta showCritical tags action = do + withAckMessage :: Text -> ConnId -> MsgMeta -> Maybe (TVar Bool) -> Bool -> Maybe (TVar [Text]) -> (Text -> CM Bool) -> CM () + withAckMessage label cId msgMeta cancelAckVar showCritical tags action = do -- [async agent commands] command should be asynchronous -- TODO catching error and sending ACK after an error, particularly if it is a database error, will result in the message not processed (and no notification to the user). -- Possible solutions are: @@ -1557,13 +1560,15 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage = eInfo <- eventInfo logInfo $ label <> ": " <> eInfo tryChatError (action eInfo) >>= \case - Right withRcpt -> - withLog (eInfo <> " ok") $ ackMsg msgMeta $ if withRcpt then Just "" else Nothing + Right withRcpt -> do + cancelAck <- maybe (pure False) readTVarIO cancelAckVar + unless cancelAck $ withLog (eInfo <> " ok") $ ackMsg msgMeta (if withRcpt then Just "" else Nothing) -- If showCritical is True, then these errors don't result in ACK and show user visible alert -- This prevents losing the message that failed to be processed. Left (ChatErrorStore SEDBBusyError {message}) | showCritical -> throwError $ ChatErrorAgent (CRITICAL True message) Nothing Left e -> do - withLog (eInfo <> " error: " <> tshow e) $ ackMsg msgMeta Nothing + cancelAck <- maybe (pure False) readTVarIO cancelAckVar + unless cancelAck $ withLog (eInfo <> " error: " <> tshow e) $ ackMsg msgMeta Nothing throwError e where eventInfo = do