merged PR 5dkZ3UqkiT hbs2-peer-median-rtt

This commit is contained in:
Dmitry Zuikov 2023-04-04 06:43:22 +03:00
parent ee04511542
commit cfd5a5bdbd
4 changed files with 52 additions and 12 deletions

View File

@ -1,3 +1,12 @@
## 2023-04-03
TODO: hbs2-peer-meidan-rtt
вычислять и выводить медианный rtt вместо последнего
PR: hbs2-peer-meidan-rtt
branch: calculate-median-rtt
commit: a9874a5727c3c16eb37e01b39832a4dfd3418c9c
Вычисление и отображение медианного RTT вместо последнего.
## 2023-04-01 ## 2023-04-01

View File

@ -491,7 +491,7 @@ blockDownloadLoop env0 = do
errors <- liftIO $ readTVarIO (view peerErrorsPerSec pinfo) errors <- liftIO $ readTVarIO (view peerErrorsPerSec pinfo)
downFails <- liftIO $ readTVarIO (view peerDownloadFail pinfo) downFails <- liftIO $ readTVarIO (view peerDownloadFail pinfo)
down <- liftIO $ readTVarIO (view peerDownloadedBlk pinfo) down <- liftIO $ readTVarIO (view peerDownloadedBlk pinfo)
rtt <- liftIO $ readTVarIO (view peerRTT pinfo) <&> fmap realToFrac rtt <- liftIO $ medianPeerRTT pinfo <&> fmap realToFrac
let rttMs = (/1e6) <$> rtt <&> (\x -> showGFloat (Just 2) x "") <&> (<> "ms") let rttMs = (/1e6) <$> rtt <&> (\x -> showGFloat (Just 2) x "") <&> (<> "ms")

View File

@ -52,12 +52,43 @@ data PeerInfo e =
, _peerDownloadedBlk :: TVar Int , _peerDownloadedBlk :: TVar Int
, _peerDownloadFail :: TVar Int , _peerDownloadFail :: TVar Int
, _peerUsefulness :: TVar Double , _peerUsefulness :: TVar Double
, _peerRTT :: TVar (Maybe Integer) -- ^ nanosec , _peerRTTBuffer :: TVar [Integer] -- ^ Contains a list of the last few round-trip time (RTT) values, measured in nanoseconds.
-- Acts like a circular buffer.
} }
deriving stock (Generic,Typeable) deriving stock (Generic,Typeable)
makeLenses 'PeerInfo makeLenses 'PeerInfo
-- | Compute the median of a list
median :: (Ord a, Integral a) => [a] -> Maybe a
median [] = Nothing
median xs = Just
if odd n
then sorted !! half
else ((sorted !! (half - 1)) + (sorted !! half)) `div` 2
where n = length xs
sorted = List.sort xs
half = n `div` 2
-- | Get the median RTT for a given peer.
medianPeerRTT :: MonadIO m => PeerInfo e -> m (Maybe Integer)
medianPeerRTT pinfo = do
rttBuffer <- liftIO $ readTVarIO (view peerRTTBuffer pinfo)
pure $ median rttBuffer
rttBufferCapacity :: Int
rttBufferCapacity = 10
-- | New values are added to the head of the list, old values are discarded when the list is full.
insertRTT :: MonadIO m => Integer -> TVar [Integer] -> m ()
insertRTT x rttList = do
liftIO $ atomically $ modifyTVar rttList (\xs ->
if rttBufferCapacity < 1
then xs
else if length xs < rttBufferCapacity
then x:xs
else x:init xs
)
newPeerInfo :: MonadIO m => m (PeerInfo e) newPeerInfo :: MonadIO m => m (PeerInfo e)
newPeerInfo = liftIO do newPeerInfo = liftIO do
@ -74,7 +105,7 @@ newPeerInfo = liftIO do
<*> newTVarIO 0 <*> newTVarIO 0
<*> newTVarIO 0 <*> newTVarIO 0
<*> newTVarIO 0 <*> newTVarIO 0
<*> newTVarIO Nothing <*> newTVarIO []
type instance SessionData e (PeerInfo e) = PeerInfo e type instance SessionData e (PeerInfo e) = PeerInfo e

View File

@ -558,12 +558,11 @@ runPeer opts = Exception.handle myException $ do
, RefLog.reflogFetch = doFetchRef , RefLog.reflogFetch = doFetchRef
} }
let doUpdateRtt (p,rttNew) = withPeerM penv $ void $ runMaybeT do let addNewRtt (p,rttNew) = withPeerM penv $ void $ runMaybeT do
def <- newPeerInfo def <- newPeerInfo
tv <- lift $ fetch True def (PeerInfoKey p) (view peerRTT) tv <- lift $ fetch True def (PeerInfoKey p) (view peerRTTBuffer)
void $ liftIO $ atomically $ writeTVar tv (Just rttNew) insertRTT rttNew tv
let hshakeAdapter = PeerHandshakeAdapter addNewRtt
let hshakeAdapter = PeerHandshakeAdapter doUpdateRtt
env <- ask env <- ask
@ -639,11 +638,12 @@ runPeer opts = Exception.handle myException $ do
debug "Same peer, different address" debug "Same peer, different address"
void $ runMaybeT do void $ runMaybeT do
tv0 <- MaybeT $ find (PeerInfoKey p0) (view peerRTT)
tv1 <- MaybeT $ find (PeerInfoKey p) (view peerRTT) pinfo0 <- MaybeT $ find (PeerInfoKey p0) id
pinfo1 <- MaybeT $ find (PeerInfoKey p) id
rtt0 <- MaybeT $ liftIO $ readTVarIO tv0 rtt0 <- MaybeT $ medianPeerRTT pinfo0
rtt1 <- MaybeT $ liftIO $ readTVarIO tv1 rtt1 <- MaybeT $ medianPeerRTT pinfo1
when ( rtt1 < rtt0 ) do when ( rtt1 < rtt0 ) do
debug $ "Better rtt!" <+> pretty p0 debug $ "Better rtt!" <+> pretty p0