Merge branch 'stable' into stable-ios

This commit is contained in:
Evgeny Poberezkin
2024-01-09 10:40:52 +00:00
35 changed files with 425 additions and 152 deletions
+30 -17
View File
@@ -233,6 +233,7 @@ newChatController
expireCIFlags <- newTVarIO M.empty
cleanupManagerAsync <- newTVarIO Nothing
timedItemThreads <- atomically TM.empty
chatActivated <- newTVarIO True
showLiveItems <- newTVarIO False
encryptLocalFiles <- newTVarIO False
userXFTPFileConfig <- newTVarIO $ xftpFileConfig cfg
@@ -268,6 +269,7 @@ newChatController
expireCIFlags,
cleanupManagerAsync,
timedItemThreads,
chatActivated,
showLiveItems,
encryptLocalFiles,
userXFTPFileConfig,
@@ -310,10 +312,10 @@ cfgServers = \case
SPSMP -> smp
SPXFTP -> xftp
startChatController :: forall m. ChatMonad' m => Bool -> Bool -> Bool -> m (Async ())
startChatController subConns enableExpireCIs startXFTPWorkers = do
startChatController :: forall m. ChatMonad' m => Bool -> m (Async ())
startChatController mainApp = do
asks smpAgent >>= resumeAgentClient
unless subConns $
unless mainApp $
chatWriteVar subscriptionMode SMOnlyCreate
users <- fromRight [] <$> runExceptT (withStoreCtx' (Just "startChatController, getUsers") getUsers)
restoreCalls
@@ -323,15 +325,15 @@ startChatController subConns enableExpireCIs startXFTPWorkers = do
start s users = do
a1 <- async agentSubscriber
a2 <-
if subConns
if mainApp
then Just <$> async (subscribeUsers False users)
else pure Nothing
atomically . writeTVar s $ Just (a1, a2)
when startXFTPWorkers $ do
when mainApp $ do
startXFTP
void $ forkIO $ startFilesToReceive users
startCleanupManager
when enableExpireCIs $ startExpireCIs users
startCleanupManager
startExpireCIs users
pure a1
startXFTP = do
tmp <- readTVarIO =<< asks tempDirectory
@@ -543,16 +545,17 @@ processChatCommand' vr = \case
checkDeleteChatUser user'
withChatLock "deleteUser" . procCmd $ deleteChatUser user' delSMPQueues
DeleteUser uName delSMPQueues viewPwd_ -> withUserName uName $ \userId -> APIDeleteUser userId delSMPQueues viewPwd_
StartChat subConns enableExpireCIs startXFTPWorkers -> withUser' $ \_ ->
StartChat mainApp -> withUser' $ \_ ->
asks agentAsync >>= readTVarIO >>= \case
Just _ -> pure CRChatRunning
_ -> checkStoreNotChanged $ startChatController subConns enableExpireCIs startXFTPWorkers $> CRChatStarted
_ -> checkStoreNotChanged $ startChatController mainApp $> CRChatStarted
APIStopChat -> do
ask >>= stopChatController
pure CRChatStopped
APIActivateChat restoreChat -> withUser $ \_ -> do
when restoreChat restoreCalls
withAgent foregroundAgent
chatWriteVar chatActivated True
when restoreChat $ do
users <- withStoreCtx' (Just "APIActivateChat, getUsers") getUsers
void . forkIO $ subscribeUsers True users
@@ -560,6 +563,7 @@ processChatCommand' vr = \case
setAllExpireCIFlags True
ok_
APISuspendChat t -> do
chatWriteVar chatActivated False
setAllExpireCIFlags False
stopRemoteCtrl
withAgent (`suspendAgent` t)
@@ -2480,6 +2484,7 @@ startExpireCIThread user@User {userId} = do
flip catchChatError (toView . CRChatError (Just user)) $ do
expireFlags <- asks expireCIFlags
atomically $ TM.lookup userId expireFlags >>= \b -> unless (b == Just True) retry
waitChatStartedAndActivated
ttl <- withStoreCtx' (Just "startExpireCIThread, getChatItemTTL") (`getChatItemTTL` user)
forM_ ttl $ \t -> expireChatItems user t False
liftIO $ threadDelay' interval
@@ -2973,7 +2978,7 @@ cleanupManager = do
stepDelay <- asks (cleanupManagerStepDelay . config)
forever $ do
flip catchChatError (toView . CRChatError Nothing) $ do
waitChatStarted
waitChatStartedAndActivated
users <- withStoreCtx' (Just "cleanupManager, getUsers 1") getUsers
let (us, us') = partition activeUser users
forM_ us $ cleanupUser interval stepDelay
@@ -2983,7 +2988,7 @@ cleanupManager = do
liftIO $ threadDelay' $ diffToMicroseconds interval
where
runWithoutInitialDelay cleanupInterval = flip catchChatError (toView . CRChatError Nothing) $ do
waitChatStarted
waitChatStartedAndActivated
users <- withStoreCtx' (Just "cleanupManager, getUsers 2") getUsers
let (us, us') = partition activeUser users
forM_ us $ \u -> cleanupTimedItems cleanupInterval u `catchChatError` (toView . CRChatError (Just u))
@@ -3038,7 +3043,7 @@ deleteTimedItem :: ChatMonad m => User -> (ChatRef, ChatItemId) -> UTCTime -> m
deleteTimedItem user (ChatRef cType chatId, itemId) deleteAt = do
ts <- liftIO getCurrentTime
liftIO $ threadDelay' $ diffToMicroseconds $ diffUTCTime deleteAt ts
waitChatStarted
waitChatStartedAndActivated
vr <- chatVersionRange
case cType of
CTDirect -> do
@@ -3064,8 +3069,10 @@ expireChatItems user@User {userId} ttl sync = do
let expirationDate = addUTCTime (-1 * fromIntegral ttl) currentTs
-- this is to keep group messages created during last 12 hours even if they're expired according to item_ts
createdAtCutoff = addUTCTime (-43200 :: NominalDiffTime) currentTs
waitChatStartedAndActivated
contacts <- withStoreCtx' (Just "expireChatItems, getUserContacts") (`getUserContacts` user)
loop contacts $ processContact expirationDate
waitChatStartedAndActivated
groups <- withStoreCtx' (Just "expireChatItems, getUserGroupDetails") (\db -> getUserGroupDetails db vr user Nothing Nothing)
loop groups $ processGroup expirationDate createdAtCutoff
where
@@ -3084,11 +3091,13 @@ expireChatItems user@User {userId} ttl sync = do
when (expire == Just True) $ threadDelay 100000 >> a
processContact :: UTCTime -> Contact -> m ()
processContact expirationDate ct = do
waitChatStartedAndActivated
filesInfo <- withStoreCtx' (Just "processContact, getContactExpiredFileInfo") $ \db -> getContactExpiredFileInfo db user ct expirationDate
deleteFilesAndConns user filesInfo
withStoreCtx' (Just "processContact, deleteContactExpiredCIs") $ \db -> deleteContactExpiredCIs db user ct expirationDate
processGroup :: UTCTime -> UTCTime -> GroupInfo -> m ()
processGroup expirationDate createdAtCutoff gInfo = do
waitChatStartedAndActivated
filesInfo <- withStoreCtx' (Just "processGroup, getGroupExpiredFileInfo") $ \db -> getGroupExpiredFileInfo db user gInfo expirationDate createdAtCutoff
deleteFilesAndConns user filesInfo
withStoreCtx' (Just "processGroup, deleteGroupExpiredCIs") $ \db -> deleteGroupExpiredCIs db user gInfo expirationDate createdAtCutoff
@@ -6114,10 +6123,14 @@ checkSameUser userId User {userId = activeUserId} = when (userId /= activeUserId
chatStarted :: ChatMonad m => m Bool
chatStarted = fmap isJust . readTVarIO =<< asks agentAsync
waitChatStarted :: ChatMonad m => m ()
waitChatStarted = do
waitChatStartedAndActivated :: ChatMonad m => m ()
waitChatStartedAndActivated = do
agentStarted <- asks agentAsync
atomically $ readTVar agentStarted >>= \a -> unless (isJust a) retry
chatActivated <- asks chatActivated
atomically $ do
started <- readTVar agentStarted
activated <- readTVar chatActivated
unless (isJust started && activated) retry
chatVersionRange :: ChatMonad' m => m VersionRange
chatVersionRange = do
@@ -6154,8 +6167,8 @@ chatCommandP =
"/_delete user " *> (APIDeleteUser <$> A.decimal <* " del_smp=" <*> onOffP <*> optional (A.space *> jsonP)),
"/delete user " *> (DeleteUser <$> displayName <*> pure True <*> optional (A.space *> pwdP)),
("/user" <|> "/u") $> ShowActiveUser,
"/_start subscribe=" *> (StartChat <$> onOffP <* " expire=" <*> onOffP <* " xftp=" <*> onOffP),
"/_start" $> StartChat True True True,
"/_start main=" *> (StartChat <$> onOffP),
"/_start" $> StartChat True,
"/_stop" $> APIStopChat,
"/_app activate restore=" *> (APIActivateChat <$> onOffP),
"/_app activate" $> APIActivateChat True,
+2 -1
View File
@@ -200,6 +200,7 @@ data ChatController = ChatController
expireCIThreads :: TMap UserId (Maybe (Async ())),
expireCIFlags :: TMap UserId Bool,
cleanupManagerAsync :: TVar (Maybe (Async ())),
chatActivated :: TVar Bool,
timedItemThreads :: TMap (ChatRef, ChatItemId) (TVar (Maybe (Weak ThreadId))),
showLiveItems :: TVar Bool,
encryptLocalFiles :: TVar Bool,
@@ -233,7 +234,7 @@ data ChatCommand
| UnmuteUser
| APIDeleteUser UserId Bool (Maybe UserPwd)
| DeleteUser UserName Bool (Maybe UserPwd)
| StartChat {subscribeConnections :: Bool, enableExpireChatItems :: Bool, startXFTPWorkers :: Bool}
| StartChat {mainApp :: Bool}
| APIStopChat
| APIActivateChat {restoreChat :: Bool}
| APISuspendChat {suspendTimeout :: Int}
+1 -1
View File
@@ -35,7 +35,7 @@ runSimplexChat :: ChatOpts -> User -> ChatController -> (User -> ChatController
runSimplexChat ChatOpts {maintenance} u cc chat
| maintenance = wait =<< async (chat u cc)
| otherwise = do
a1 <- runReaderT (startChatController True True True) cc
a1 <- runReaderT (startChatController True) cc
a2 <- async $ chat u cc
waitEither_ a1 a2