[Haskell-cafe] IO and exceptions

Roman Cheplyaka roma at ro-che.info
Sun Nov 9 13:11:41 UTC 2014


Let's say you knew what exceptions could be thrown. What would you do
differently then?

Typically, if it's a command-line app and something unexpected happens,
you simply present the error to the user. That's what exceptions do
already without any effort from you.

If it's a server app, you catch exceptions at a certain point, log them,
maybe give some feedback to the client and proceed with the other
requests. In order to do that, you don't really need to know the set of
all possible exceptions.

> `readChan` blocks the thread until it reads something. But what
> happens when channel is closed while one thread is blocked to read?

What do you mean by "channel is closed"? Channels don't get closed;
there's no function to do that.

It's possible that your blocked thread has the only remaining reference
to the channel; in that case, the deadlock may (or may not) be detected,
and an exception will be thrown in the former case.

> Example to not being able to catch the exception:
> http://hackage.haskell.org/package/network-2.6.0.2/docs/Network-Socket.html
> `recvFrom` blocks the thread until it reads something. However, what
> happens if socket is closed while `recvFrom` is blocking to read?
> Similar to `readChan`, we can't know this. What's worse is this:
> sockets have a `SO_RCVTIMEO` option, a timeout value for `recv_from`
> calls. What happens when we set that using `setSocketOption` in the
> same module and call `recvFrom` is unknown. This is really horrible,
> because a timeout exception is really something that you'd like to
> catch. Example: I have a thread that listens from a socket and handles
> some other events. I want to stop listening the socket after every
> second and handle events, then return listening the socket. But I
> can't know what it throws when timeout happens, so I have to catch all
> exceptions, which is horrible for a lot of reasons.

It sounds like you're trying to write C-style in Haskell, which is
probably not the best way to do it.

More Haskelly way would be to:

1. Use Network instead of Network.Socket and take advantage of GHC's IO
manager. That means that you'll be using something like epoll instead of
recvfrom under the hood.
2. Instead of manually multiplexing several things into one thread
(listening on the socket and "handling some other events"), do that in
different threads.
3. If you do need a timeout (not for multiplexing, but for a genuine
timeout), use System.Timeout.


Roman


More information about the Haskell-Cafe mailing list