|Portability||Requires GHC 7+|
Create a new
Delay that will ring in the given number of microseconds.
Waiting for expiration
Suppose we are managing a network connection, and want to time it out if no
messages are received in over five minutes. We'll create a
Delay, and an
action to "bump" it:
let timeoutInterval = 5 * 60 * 1000000 ::
newDelaytimeoutInterval let bump =
This way, the
Delay will ring if it is not bumped for longer than
Now we fork the receiver thread:
forever$ do msg <- recvMessage bump handleMessage msg ) `finally`
Finally, we wait for the delay to ring, or for the receiver thread to fail due to an exception:
- If handleMessage blocks, the
Delaymay ring due to
handleMessagetaking too long, rather than just
recvMessagetaking too long.
- The loop will continue to run until you do something to stop it.
It might be simpler to use System.Timeout instead:
timeouttimeoutInterval recvMessage case m of Nothing ->
fail"timed out" Just msg -> handleMessage msg
However, using a
Delay has the following advantages:
recvMessagemakes a blocking FFI call (e.g. network I/O on Windows),
timeoutwon't work, since it uses an asynchronous exception, and FFI calls can't be interrupted with async exceptions. The
Delayapproach lets you handle the timeout in another thread, while the FFI call is still blocked.
updateDelayis more efficient than
timeoutwhen GHC.Event is available.