module Network.Control.Rate (
Rate,
newRate,
getRate,
addRate,
) where
import Data.IORef
import Data.UnixTime
newtype Rate = Rate (IORef Counter)
data Counter = Counter Int UnixTime
newRate :: IO Rate
newRate :: IO Rate
newRate = do
cntr <- Int -> UnixTime -> Counter
Counter Int
0 (UnixTime -> Counter) -> IO UnixTime -> IO Counter
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO UnixTime
getUnixTime
Rate <$> newIORef cntr
getRate :: Rate -> IO Int
getRate :: Rate -> IO Int
getRate Rate
r = Rate -> Int -> IO Int
addRate Rate
r Int
1
addRate :: Rate -> Int -> IO Int
addRate :: Rate -> Int -> IO Int
addRate (Rate IORef Counter
ref) Int
x = do
Counter n beg <- IORef Counter -> IO Counter
forall a. IORef a -> IO a
readIORef IORef Counter
ref
cur <- getUnixTime
if (cur `diffUnixTime` beg) > 1
then do
let n' = Int
x
writeIORef ref $ Counter n' cur
return n'
else do
let n' = Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
x
writeIORef ref $ Counter n' beg
return n'