@@ -14,6 +14,8 @@ import Data.ByteString.Char8 (ByteString)
1414import qualified Data.ByteString.Char8 as B
1515import Data.Hashable (hash )
1616import Data.IORef
17+ import Data.Int (Int64 )
18+ import qualified Data.IntMap.Strict as IM
1719import Data.IntSet (IntSet )
1820import qualified Data.IntSet as IS
1921import Data.Set (Set )
@@ -25,6 +27,7 @@ import Data.Time.Clock (UTCTime (..))
2527import GHC.IORef (atomicSwapIORef )
2628import Simplex.Messaging.Encoding.String
2729import Simplex.Messaging.Protocol (EntityId (.. ))
30+ import Simplex.Messaging.Server.QueueStore (RoundedSystemTime (.. ))
2831import Simplex.Messaging.Util (atomicModifyIORef'_ , tshow , unlessM )
2932
3033data ServerStats = ServerStats
@@ -57,6 +60,7 @@ data ServerStats = ServerStats
5760 msgSentLarge :: IORef Int ,
5861 msgSentBlock :: IORef Int ,
5962 msgRecv :: IORef Int ,
63+ msgRecvAckTimes :: IORef TimeBuckets ,
6064 msgRecvGet :: IORef Int ,
6165 msgGet :: IORef Int ,
6266 msgGetNoMsg :: IORef Int ,
@@ -115,6 +119,7 @@ data ServerStatsData = ServerStatsData
115119 _msgSentLarge :: Int ,
116120 _msgSentBlock :: Int ,
117121 _msgRecv :: Int ,
122+ _msgRecvAckTimes :: TimeBuckets ,
118123 _msgRecvGet :: Int ,
119124 _msgGet :: Int ,
120125 _msgGetNoMsg :: Int ,
@@ -174,6 +179,7 @@ newServerStats ts = do
174179 msgSentLarge <- newIORef 0
175180 msgSentBlock <- newIORef 0
176181 msgRecv <- newIORef 0
182+ msgRecvAckTimes <- newIORef $ TimeBuckets 0 0 IM. empty
177183 msgRecvGet <- newIORef 0
178184 msgGet <- newIORef 0
179185 msgGetNoMsg <- newIORef 0
@@ -230,6 +236,7 @@ newServerStats ts = do
230236 msgSentLarge,
231237 msgSentBlock,
232238 msgRecv,
239+ msgRecvAckTimes,
233240 msgRecvGet,
234241 msgGet,
235242 msgGetNoMsg,
@@ -288,6 +295,7 @@ getServerStatsData s = do
288295 _msgSentLarge <- readIORef $ msgSentLarge s
289296 _msgSentBlock <- readIORef $ msgSentBlock s
290297 _msgRecv <- readIORef $ msgRecv s
298+ _msgRecvAckTimes <- readIORef $ msgRecvAckTimes s
291299 _msgRecvGet <- readIORef $ msgRecvGet s
292300 _msgGet <- readIORef $ msgGet s
293301 _msgGetNoMsg <- readIORef $ msgGetNoMsg s
@@ -344,6 +352,7 @@ getServerStatsData s = do
344352 _msgSentLarge,
345353 _msgSentBlock,
346354 _msgRecv,
355+ _msgRecvAckTimes,
347356 _msgRecvGet,
348357 _msgGet,
349358 _msgGetNoMsg,
@@ -403,6 +412,7 @@ setServerStats s d = do
403412 writeIORef (msgSentLarge s) $! _msgSentLarge d
404413 writeIORef (msgSentBlock s) $! _msgSentBlock d
405414 writeIORef (msgRecv s) $! _msgRecv d
415+ writeIORef (msgRecvAckTimes s) $! _msgRecvAckTimes d
406416 writeIORef (msgRecvGet s) $! _msgRecvGet d
407417 writeIORef (msgGet s) $! _msgGet d
408418 writeIORef (msgGetNoMsg s) $! _msgGetNoMsg d
@@ -462,6 +472,7 @@ instance StrEncoding ServerStatsData where
462472 " msgSentLarge=" <> strEncode (_msgSentLarge d),
463473 " msgSentBlock=" <> strEncode (_msgSentBlock d),
464474 " msgRecv=" <> strEncode (_msgRecv d),
475+ " msgRecvAckTimes=" <> strEncode (_msgRecvAckTimes d),
465476 " msgRecvGet=" <> strEncode (_msgRecvGet d),
466477 " msgGet=" <> strEncode (_msgGet d),
467478 " msgGetNoMsg=" <> strEncode (_msgGetNoMsg d),
@@ -525,6 +536,7 @@ instance StrEncoding ServerStatsData where
525536 _msgSentLarge <- opt " msgSentLarge="
526537 _msgSentBlock <- opt " msgSentBlock="
527538 _msgRecv <- " msgRecv=" *> strP <* A. endOfLine
539+ _msgRecvAckTimes <- " msgRecvAckTimes=" *> strP <* A. endOfLine <|> pure (TimeBuckets 0 0 IM. empty)
528540 _msgRecvGet <- opt " msgRecvGet="
529541 _msgGet <- opt " msgGet="
530542 _msgGetNoMsg <- opt " msgGetNoMsg="
@@ -592,6 +604,7 @@ instance StrEncoding ServerStatsData where
592604 _msgSentLarge,
593605 _msgSentBlock,
594606 _msgRecv,
607+ _msgRecvAckTimes,
595608 _msgRecvGet,
596609 _msgGet,
597610 _msgGetNoMsg,
@@ -944,3 +957,38 @@ instance StrEncoding ServiceStatsData where
944957 _srvSubQueues,
945958 _srvSubEnd
946959 }
960+
961+ data TimeBuckets = TimeBuckets
962+ { sumTime :: Int64 ,
963+ maxTime :: Int64 ,
964+ timeBuckets :: IM. IntMap Int
965+ }
966+ deriving (Show )
967+
968+ updateTimeBuckets :: RoundedSystemTime -> RoundedSystemTime -> TimeBuckets -> TimeBuckets
969+ updateTimeBuckets
970+ (RoundedSystemTime deliveryTime)
971+ (RoundedSystemTime currTime)
972+ TimeBuckets {sumTime, maxTime, timeBuckets} =
973+ TimeBuckets
974+ { sumTime = sumTime + t,
975+ maxTime = max maxTime t,
976+ timeBuckets = IM. alter (Just . maybe 1 (+ 1 )) seconds timeBuckets
977+ }
978+ where
979+ t = currTime - deliveryTime
980+ seconds
981+ | t <= 5 = fromIntegral t
982+ | t <= 30 = t `toBucket` 5
983+ | t <= 60 = t `toBucket` 10
984+ | t <= 180 = t `toBucket` 30
985+ | otherwise = t `toBucket` 60
986+ toBucket n m = - fromIntegral (((- n) `div` m) * m) -- round up
987+
988+ instance StrEncoding TimeBuckets where
989+ strEncode TimeBuckets {sumTime, maxTime, timeBuckets} =
990+ strEncode (sumTime, maxTime) <> " " <> strEncodeList (IM. toList timeBuckets)
991+ strP = do
992+ (sumTime, maxTime) <- strP_
993+ tbs <- strListP
994+ pure TimeBuckets {sumTime, maxTime, timeBuckets = IM. fromList tbs}
0 commit comments