1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
|
module Network.Control.Rate (
-- * Rate control
Rate,
newRate,
getRate,
addRate,
) where
import Data.IORef
import Data.UnixTime
-- | Type for rating.
newtype Rate = Rate (IORef Counter)
data Counter = Counter Int UnixTime
-- | Creating a new 'Rate'.
newRate :: IO Rate
newRate = do
cntr <- Counter 0 <$> getUnixTime
Rate <$> newIORef cntr
-- | Getting the current rate.
-- If one or more seconds have passed since the previous call, the
-- counter is re-initialized with 1 and it is returned. Otherwise,
-- incremented counter number is returned.
getRate :: Rate -> IO Int
getRate r = addRate r 1
-- | Getting the current rate.
-- If one or more seconds have passed since the previous call, the
-- counter is re-initialized with the second argument and it is
-- returned. Otherwise, increased counter number is returned.
addRate :: Rate -> Int -> IO Int
addRate (Rate ref) x = do
Counter n beg <- readIORef ref
cur <- getUnixTime
if (cur `diffUnixTime` beg) > 1
then do
let n' = x
writeIORef ref $ Counter n' cur
return n'
else do
let n' = n + x
writeIORef ref $ Counter n' beg
return n'
|