Portability | uses mdo |
---|
Timeout implementation for performing operations in the IO monad with a timeout added. Both using Maybe and exceptions to handle timeouts are supported.
Timeouts can be implemented in GHC with either a global handler or a per-timeout thread which sleeps until the timeout. The latter is used in this module. Blocking on foreign calls can cause problems as GHC has no way of interrupting such threads. The module provides a slightly slower alternative implementation which returns even if the computation has blocked on a foreign call. This should not be an issue unless -threaded is used.
The timeouts are currently limited to a maximum of about 2000 seconds. This is a feature of threadDelay, but supporting longer timeouts is certainly possible if that is desirable.
For nested timeouts there are different ways to implement them: a) attach an id to the exception so that the catch knows wether it may catch this timout exception. I've choosen this because overhead is only passing and incrementing an integer value. A integer wrap araound is possible but too unlikely to happen to make me worry about it b) start a new workiing and killing thread so that if the original thread was run within withTimeOut itself it catches the exception and not an inner timout. (this is done in withSafeTimeOut, for another reason though) c) keep throwing exceptions until the the withTimeOut function kills the killing thread. But consider sequence (forever (timeOut threadDelay 10sec) ) In this case the exception will be called and the next timOut may be entered before the second Exception has been thrown
All exceptions but the internal TimeOutExceptionI are rethrown in the calling thread
- withTimeOut :: Int -> IO a -> IO a
- withTimeOutMaybe :: Int -> IO a -> IO (Maybe a)
- withSafeTimeOut :: Int -> IO a -> IO a
- withSafeTimeOutMaybe :: Int -> IO a -> IO (Maybe a)
- data TimeOutException = TimeOutException
- second :: Int
Documentation
withTimeOut :: Int -> IO a -> IO aSource
This is the normal timeout handler. It throws a TimeOutException exception, if the timeout occurs.
withTimeOutMaybe :: Int -> IO a -> IO (Maybe a)Source
This handler returns Nothing
if the timeout occurs and Just a
if computation
returns a
.
withSafeTimeOut :: Int -> IO a -> IO aSource
Like timeOut, but additionally it works even if the computation is blocking async exceptions (explicitely or by a blocking FFI call). This consumes more resources than timeOut, but is still quite fast.
withSafeTimeOutMaybe :: Int -> IO a -> IO (Maybe a)Source
Like withTimeOutMaybe, but handles the operation blocking exceptions like withSafeTimeOut does.
data TimeOutException Source