Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automatically reconnect a Haskell Network connection in an idiomatic way

Tags:

haskell

I've worked my way through Don Stewart's Roll your own IRC bot tutorial, and am playing around with some extensions to it. My current code is essentially the same as the "The monadic, stateful, exception-handling bot in all its glory"; it's a bit too long to paste here unless someone requests it.

Being a Comcast subscriber, it's particularly important that the bot be able to reconnect after periods of poor connectivity. My approach is to simply time the PING requests from the server, and if it goes without seeing a PING for a certain time, to try reconnecting.

So far, the best solution I've found is to wrap the hGetLine in the listen loop with System.Timeout.timeout. However, this seems to require defining a custom exception so that the catch in main can call main again, rather than return (). It also seems quite fragile to specify a timeout value for each individual hGetLine.

Is there a better solution, perhaps something that wraps an IO a like bracket and catch so that the entire main can handle network timeouts without the overhead of a new exception type?

like image 540
acfoltzer Avatar asked Apr 12 '11 00:04

acfoltzer


1 Answers

How about running a separate thread that performs all the reading and writing and takes care of periodically reconnecting the handle?

Something like this

 input  :: Chan Char
 output :: Chan Char

 putChar c = writeChan output c

 keepAlive = forever $ do
     h <- connectToServer
     catch
         (forever $
              do c <- readChan output; timeout 4000 (hPutChar h c); return ())
         (\_ -> return ())

The idea is to encapsulate all the difficulty with periodically reconnecting into a separate thread.

like image 100
Heinrich Apfelmus Avatar answered Sep 19 '22 15:09

Heinrich Apfelmus