smp server: remove store log backups when server starts (#1472)

This commit is contained in:
Evgeny
2025-02-27 07:39:05 +00:00
committed by GitHub
parent f9d7b1eebc
commit 205d4ead1c

View File

@@ -37,14 +37,16 @@ import Control.Applicative (optional, (<|>))
import Control.Concurrent.STM import Control.Concurrent.STM
import qualified Control.Exception as E import qualified Control.Exception as E
import Control.Logger.Simple import Control.Logger.Simple
import Control.Monad (when) import Control.Monad
import qualified Data.Attoparsec.ByteString.Char8 as A import qualified Data.Attoparsec.ByteString.Char8 as A
import qualified Data.ByteString.Char8 as B import qualified Data.ByteString.Char8 as B
import Data.Functor (($>)) import Data.Functor (($>))
import Data.List (sort, stripPrefix)
import qualified Data.Map.Strict as M import qualified Data.Map.Strict as M
import Data.Maybe (mapMaybe)
import qualified Data.Text as T import qualified Data.Text as T
import Data.Time.Clock (getCurrentTime) import Data.Time.Clock (UTCTime, addUTCTime, getCurrentTime, nominalDay)
import Data.Time.Format.ISO8601 (iso8601Show) import Data.Time.Format.ISO8601 (iso8601Show, iso8601ParseM)
import GHC.IO (catchAny) import GHC.IO (catchAny)
import Simplex.Messaging.Encoding.String import Simplex.Messaging.Encoding.String
import Simplex.Messaging.Protocol import Simplex.Messaging.Protocol
@@ -53,8 +55,9 @@ import Simplex.Messaging.Server.QueueStore
import Simplex.Messaging.Server.StoreLog.Types import Simplex.Messaging.Server.StoreLog.Types
import qualified Simplex.Messaging.TMap as TM import qualified Simplex.Messaging.TMap as TM
import Simplex.Messaging.Util (ifM, tshow, unlessM, whenM) import Simplex.Messaging.Util (ifM, tshow, unlessM, whenM)
import System.Directory (doesFileExist, renameFile) import System.Directory (doesFileExist, listDirectory, removeFile, renameFile)
import System.IO import System.IO
import System.FilePath (takeDirectory, takeFileName)
data StoreLogRecord data StoreLogRecord
= CreateQueue RecipientId QueueRec = CreateQueue RecipientId QueueRec
@@ -237,6 +240,7 @@ readWriteStoreLog readStore writeStore f st =
renameFile f tempBackup -- 1) make temp backup renameFile f tempBackup -- 1) make temp backup
s <- writeLog "compacting store log (do not terminate)..." -- 2) save state s <- writeLog "compacting store log (do not terminate)..." -- 2) save state
renameBackup -- 3) timed backup renameBackup -- 3) timed backup
removeStoreLogBackups f
pure s pure s
writeLog msg = do writeLog msg = do
s <- openWriteStoreLog f s <- openWriteStoreLog f
@@ -258,6 +262,27 @@ writeQueueStore s st = readTVarIO qs >>= mapM_ writeQueue . M.assocs
Just q' -> logCreateQueue s rId q' Just q' -> logCreateQueue s rId q'
Nothing -> atomically $ TM.delete rId qs Nothing -> atomically $ TM.delete rId qs
removeStoreLogBackups :: FilePath -> IO ()
removeStoreLogBackups f = do
ts <- getCurrentTime
times <- sort . mapMaybe backupPathTime <$> listDirectory (takeDirectory f)
let new = addUTCTime (- nominalDay) ts
old = addUTCTime (- oldBackupTTL) ts
times1 = filter (< new) times -- exclude backups newer than 24 hours
times2 = take (length times1 - minOldBackups) times1 -- keep 3 backups older than 24 hours
toDelete = filter (< old) times2 -- remove all backups older than 21 day
mapM_ (removeFile . backupPath) toDelete
putStrLn $ "Removed " <> show (length toDelete) <> " backups:"
mapM_ (putStrLn . backupPath) toDelete
where
backupPathTime :: FilePath -> Maybe UTCTime
backupPathTime = iso8601ParseM <=< stripPrefix backupPathPfx
backupPath :: UTCTime -> FilePath
backupPath ts = f <> "." <> iso8601Show ts
backupPathPfx = takeFileName f <> "."
minOldBackups = 3
oldBackupTTL = 21 * nominalDay
readLogLines :: Bool -> FilePath -> (Bool -> B.ByteString -> IO ()) -> IO () readLogLines :: Bool -> FilePath -> (Bool -> B.ByteString -> IO ()) -> IO ()
readLogLines tty f action = foldLogLines tty f (const action) () readLogLines tty f action = foldLogLines tty f (const action) ()