module Control.Observable.Usage.Heartbeat (alive) where import "base" Control.Applicative ((*>), pure) import "base" Control.Concurrent (threadDelay) import "base" Control.Monad ((>>=)) import "base" Data.Either (either) import "base" Data.Function (($), (.), const) import "base" Data.Int (Int) import "base" System.IO (IO) import "async" Control.Concurrent.Async (race) import Control.Observable (Observable, obs, notify) data Beaten a = Alive a | Dead -- | Listen event from action untill time limit is up alive :: Int -> Observable IO a r -> (a -> IO r) -> IO (Beaten r) alive limit r f = race (threadDelay limit) (notify r f) >>= either (const . pure $ Dead) ((*>) (alive limit r f) . pure . Alive)