{-# LANGUAGE RecordWildCards #-} module Concurrent.Internal.Backoff where import Control.Concurrent data Backoff = Backoff { current , cap , totalWait :: {-# UNPACK #-} !Int } defaultBackoff :: Backoff defaultBackoff = Backoff 0 10000 0 -- 10ms backoff :: Backoff -> IO Backoff backoff b@Backoff{..} | current < 1 = do yield return b { current = current + 1 } | otherwise = do threadDelay current return b { current = min cap (2*current), totalWait = totalWait + current }