Stability | unstable |
---|---|
Maintainer | Fedor Gogolev <knsd@knsd.net> |
Safe Haskell | None |
- data NominalDiffTime
- newtype Timeout = Timeout Unique
- timeout :: (MonadMask m, MonadIO m) => NominalDiffTime -> m a -> m (Maybe a)
- sleep :: MonadIO m => NominalDiffTime -> m ()
Documentation
data NominalDiffTime
This is a length of time, as measured by UTC. Conversion functions will treat it as seconds. It has a precision of 10^-12 s. It ignores leap-seconds, so it's not necessarily a fixed amount of clock time. For instance, 23:00 UTC + 2 hours of NominalDiffTime = 01:00 UTC (+ 1 day), regardless of whether a leap-second intervened.
Exception used for timeout handling
timeout :: (MonadMask m, MonadIO m) => NominalDiffTime -> m a -> m (Maybe a)Source
Wrap an MonadIO
computation to time out and return Nothing
in case no result
is available within n
seconds. In case a result
is available before the timeout expires, Just a
is returned. A negative
timeout interval means "timeout immediately".
The design of this combinator was guided by the objective that timeout n f
should behave exactly the same as f
as long as f
doesn't time out. This
means that f
has the same myThreadId
it would have without the timeout
wrapper. Any exceptions f
might throw cancel the timeout and propagate
further up. It also possible for f
to receive exceptions thrown to it by
another thread.
A tricky implementation detail is the question of how to abort an IO
computation. This combinator relies on asynchronous exceptions internally.
The technique works very well for computations executing inside of the
Haskell runtime system, but it doesn't work at all for non-Haskell code.
Foreign function calls, for example, cannot be timed out with this
combinator simply because an arbitrary C function cannot receive
asynchronous exceptions. When timeout
is used to wrap an FFI call that
blocks, no timeout event can be delivered until the FFI call returns, which
pretty much negates the purpose of the combinator. In practice, however,
this limitation is less severe than it may sound. Standard I/O functions
like hGetBuf
, hPutBuf
, Network.Socket.accept, or
hWaitForInput
appear to be blocking, but they really don't
because the runtime system uses scheduling mechanisms like select(2)
to
perform asynchronous I/O, so it is possible to interrupt standard socket
I/O or file I/O using this combinator.
sleep :: MonadIO m => NominalDiffTime -> m ()Source
Sleep for NominalDiffTime
, example:
sleep 5 -- Will sleep for 5 seconds