
Are you doing this all in a single thread?
On Tue, Aug 26, 2008 at 4:35 PM, brian
Hi, I've been struggling with this problem for days and I'm dying. Please help.
I want to use Parsec to parse NNTP data coming to me from a handle I get from connectTo.
One unworkable approach I tried is to get a lazy String from the handle with hGetContents. The problem: suppose the first message from the NNTP server is "200 OK\r\n". Parsec parses it beautifully. Now I need to discard the parsed part so that Parsec will parse whatever the server sends next, so I use Parsec's getInput to get the remaining data. But there isn't any, so it blocks. Deadlock: the client is inappropriately waiting for server data and the server is waiting for my first command.
Another approach that doesn't quite work is to create an instance of Parsec's Stream with timeout functionality:
instance Stream Handle IO Char where uncons h = do r <- hWaitForInput h ms if r then liftM (\c -> Just (c, h)) (hGetChar h) else return Nothing where ms = 5000
It's probably obvious to you why it doesn't work, but it wasn't to me at first. The problem: suppose you tell parsec you're looking for (many digit) followed by (string "\r\n"). "123\r\n" won't match; "123\n" will. My Stream has no backtracking. Even if you don't need 'try', it won't work for even basic stuff.
Here's another way: http://www.mail-archive.com/haskell-cafe@haskell.org/msg22385.html The OP had the same problem I did, so he made a variant of hGetContents with timeout support. The problem: he used something from unsafe*. I came to Haskell for rigor and reliability and it would make me really sad to have to use a function with 'unsafe' in its name that has a lot of wacky caveats about inlining, etc.
In that same thread, Bulat says a timeout-enabled Stream could help. But I can't tell what library that is. 'cabal list stream' shows me 3 libraries none of which seems to be the one in question. Is Streams a going concern? Should I be checking that out?
I'm not doing anything with hGetLine because 1) there's no way to specify a maximum number of characters to read 2) what is meant by a "line" is not specified 3) there is no way to tell if it read a line or just got to the end of the data. Even using something like hGetLine that worked better would make the parsing more obscure.
Thank you very very much for *any* help. _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- /jve