rename "stop switch" -> "abort switch", add canAbortSwitch to rcv queue info (#775)

This commit is contained in:
spaced4ndy
2023-06-16 13:41:01 +04:00
committed by GitHub
parent 011e1109e9
commit 2efe1496d2
4 changed files with 53 additions and 49 deletions

View File

@@ -63,7 +63,7 @@ module Simplex.Messaging.Agent
sendMessage,
ackMessage,
switchConnection,
stopConnectionSwitch,
abortConnectionSwitch,
suspendConnection,
deleteConnection,
deleteConnections,
@@ -269,9 +269,9 @@ ackMessage c = withAgentEnv c .: ackMessage' c
switchConnection :: AgentErrorMonad m => AgentClient -> ConnId -> m ConnectionStats
switchConnection c = withAgentEnv c . switchConnection' c
-- | Stop switching connection to the new receive queue
stopConnectionSwitch :: AgentErrorMonad m => AgentClient -> ConnId -> m ConnectionStats
stopConnectionSwitch c = withAgentEnv c . stopConnectionSwitch' c
-- | Abort switching connection to the new receive queue
abortConnectionSwitch :: AgentErrorMonad m => AgentClient -> ConnId -> m ConnectionStats
abortConnectionSwitch c = withAgentEnv c . abortConnectionSwitch' c
-- | Suspend SMP agent connection (OFF command)
suspendConnection :: AgentErrorMonad m => AgentClient -> ConnId -> m ()
@@ -1240,13 +1240,13 @@ switchDuplexConnection c (DuplexConnection cData@ConnData {connId, userId} rqs s
let rqs' = updatedQs rq1 rqs <> [rq']
pure . connectionStats $ DuplexConnection cData rqs' sqs
stopConnectionSwitch' :: AgentMonad m => AgentClient -> ConnId -> m ConnectionStats
stopConnectionSwitch' c connId =
withConnLock c connId "stopConnectionSwitch" $
abortConnectionSwitch' :: AgentMonad m => AgentClient -> ConnId -> m ConnectionStats
abortConnectionSwitch' c connId =
withConnLock c connId "abortConnectionSwitch" $
withStore c (`getConn` connId) >>= \case
SomeConn _ (DuplexConnection cData rqs sqs) -> case switchingRQ rqs of
Just rq
| canStopRcvSwitch rq -> do
| canAbortRcvSwitch rq -> do
-- multiple queues to which the connections switches were possible when repeating switch was allowed
let (delRqs, keepRqs) = L.partition ((Just (dbQId rq) ==) . dbReplaceQId) rqs
case L.nonEmpty keepRqs of
@@ -1263,18 +1263,6 @@ stopConnectionSwitch' c connId =
_ -> throwError $ CMD PROHIBITED
_ -> throwError $ CMD PROHIBITED
canStopRcvSwitch :: RcvQueue -> Bool
canStopRcvSwitch = maybe False canStop . rcvSwchStatus
where
canStop = \case
RSSwitchStarted -> True
RSSendingQADD -> True
-- if switch is in RSSendingQUSE, a race condition with sender deleting the original queue is possible
RSSendingQUSE -> False
-- if switch is in RSReceivedMessage status, stopping switch (deleting new queue)
-- will break the connection because the sender would have original queue deleted
RSReceivedMessage -> False
ackQueueMessage :: AgentMonad m => AgentClient -> RcvQueue -> SMP.MsgId -> m ()
ackQueueMessage c rq srvMsgId =
sendAck c rq srvMsgId `catchError` \case

View File

@@ -561,19 +561,23 @@ instance FromJSON SndSwitchStatus where
data RcvQueueInfo = RcvQueueInfo
{ rcvServer :: SMPServer,
rcvSwitchStatus :: Maybe RcvSwitchStatus
rcvSwitchStatus :: Maybe RcvSwitchStatus,
canAbortSwitch :: Bool
}
deriving (Eq, Show, Generic)
instance ToJSON RcvQueueInfo where toEncoding = J.genericToEncoding J.defaultOptions {J.omitNothingFields = True}
instance StrEncoding RcvQueueInfo where
strEncode RcvQueueInfo {rcvServer, rcvSwitchStatus} =
"srv=" <> strEncode rcvServer <> maybe "" (\switch -> ";switch=" <> strEncode switch) rcvSwitchStatus
strEncode RcvQueueInfo {rcvServer, rcvSwitchStatus, canAbortSwitch} =
"srv=" <> strEncode rcvServer
<> maybe "" (\switch -> ";switch=" <> strEncode switch) rcvSwitchStatus
<> (";can_abort_switch=" <> strEncode canAbortSwitch)
strP = do
rcvServer <- "srv=" *> strP
rcvSwitchStatus <- optional $ ";switch=" *> strP
pure RcvQueueInfo {rcvServer, rcvSwitchStatus}
canAbortSwitch <- ";can_abort_switch=" *> strP
pure RcvQueueInfo {rcvServer, rcvSwitchStatus, canAbortSwitch}
data SndQueueInfo = SndQueueInfo
{ sndServer :: SMPServer,

View File

@@ -83,8 +83,20 @@ data RcvQueue = RcvQueue
deriving (Eq, Show)
rcvQueueInfo :: RcvQueue -> RcvQueueInfo
rcvQueueInfo RcvQueue {server, rcvSwchStatus} =
RcvQueueInfo {rcvServer = server, rcvSwitchStatus = rcvSwchStatus}
rcvQueueInfo rq@RcvQueue {server, rcvSwchStatus} =
RcvQueueInfo {rcvServer = server, rcvSwitchStatus = rcvSwchStatus, canAbortSwitch = canAbortRcvSwitch rq}
canAbortRcvSwitch :: RcvQueue -> Bool
canAbortRcvSwitch = maybe False canAbort . rcvSwchStatus
where
canAbort = \case
RSSwitchStarted -> True
RSSendingQADD -> True
-- if switch is in RSSendingQUSE, a race condition with sender deleting the original queue is possible
RSSendingQUSE -> False
-- if switch is in RSReceivedMessage status, aborting switch (deleting new queue)
-- will break the connection because the sender would have original queue deleted
RSReceivedMessage -> False
data ClientNtfCreds = ClientNtfCreds
{ -- | key pair to be used by the notification server to sign transmissions