-
Notifications
You must be signed in to change notification settings - Fork 98
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use exponential distribution for P2P session timeouts #1244
base: master
Are you sure you want to change the base?
Changes from 7 commits
120598a
470069d
47d6ef2
cf4d6f2
14223b2
edb5bf7
c184777
4f0cce4
c41ecff
b5fb6ad
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,8 +3,10 @@ | |
{-# LANGUAGE DeriveAnyClass #-} | ||
{-# LANGUAGE DeriveGeneric #-} | ||
{-# LANGUAGE DerivingStrategies #-} | ||
{-# LANGUAGE FlexibleContexts #-} | ||
{-# LANGUAGE LambdaCase #-} | ||
{-# LANGUAGE MultiWayIf #-} | ||
{-# LANGUAGE NumericUnderscores #-} | ||
{-# LANGUAGE OverloadedStrings #-} | ||
{-# LANGUAGE RankNTypes #-} | ||
{-# LANGUAGE ScopedTypeVariables #-} | ||
|
@@ -585,26 +587,43 @@ newSession conf node = do | |
let env = peerClientEnv node newPeerInfo | ||
(info, newSes) <- mask $ \restore -> do | ||
now <- getCurrentTimeIntegral | ||
t <- R.randomRIO | ||
( round (0.9 * timeoutMs) | ||
, round (1.1 * timeoutMs) | ||
) | ||
!newSes <- async $ restore $ timeout t | ||
t <- sessionTimeout $ secondsToTimeSpan $ _p2pConfigSessionTimeout conf | ||
!newSes <- async $ restore $ timeout (int $ timeSpanToMicros t) | ||
$ _p2pNodeClientSession node (loggFun node) env newPeerInfo | ||
incrementActiveSessionCount peerDb newPeerInfo | ||
!info <- atomically $ addSession node newPeerInfo newSes now | ||
return (info, newSes) | ||
logg node Debug $ "Started peer session " <> showSessionId newPeerInfo newSes | ||
loggFun node Info $ JsonLog info | ||
where | ||
TimeSpan timeoutMs = secondsToTimeSpan @Double (_p2pConfigSessionTimeout conf) | ||
peerDb = _p2pNodePeerDb node | ||
|
||
syncFromPeer_ pinfo | ||
| _p2pConfigPrivate conf = return True | ||
| _p2pNodeDoPeerSync node = syncFromPeer node pinfo | ||
| otherwise = return True | ||
|
||
-- | (Roughly) exponentially distributed timespans with the given expectation | ||
-- within the range of a a tenth of the expectation and ten times the | ||
-- expectation. | ||
-- | ||
-- The expected value of the actual distribution gets increasinly imprecise | ||
-- as the input value gets smaller, because a minimum result of 5 seconds | ||
-- is implemented. Input values of less than 30s should be avoided. | ||
-- | ||
sessionTimeout :: TimeSpan Int -> IO (TimeSpan Int) | ||
sessionTimeout expected = do | ||
x <- exponential (1 / us) :: IO Double | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd like to use it. However, I run into compatibility issues with our rather old nix snapshot. I don't remember the details. However, this implementation should be the same than what is used in mac-random. Also, I think, modern versions of the random package have much better performance than previous versions. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lars -- mwc-random was already in the deps list? |
||
return $! microsToTimeSpan $ round $ max lower $ min upper x | ||
where | ||
us = int $ timeSpanToMicros expected | ||
lower = max 5_000_000 (us / 10) -- at least 5 seconds | ||
upper = us * 10 | ||
|
||
exponential rate = do | ||
!x <- R.getStdRandom (R.randomR (0, 1)) | ||
return $! - log x / rate | ||
|
||
-- | Monitor and garbage collect sessions | ||
-- | ||
awaitSessions :: P2pNode -> IO () | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While you're here -- maybe make these functions strict?