Hi! I would like to make an one-directional inter-process communication in a way that one process is printing out read-compatible Haskell data types and Haskell program is reading them from a pipe. I would like to make a function which would return Nothing if there is no data type in a pipe or Just last data type there was in a pipe (discarding all before). So it should behave in a non-blocking way.
In an attempt I made this: getLastMyData :: MyState (Maybe MyData) getLastMyData = do p <- gets process case p of Nothing -> fail "No process" Just (MyProcess processOut processPid processBuffer) -> do processRunning <- io $ getProcessExitCode processPid case processRunning of Just _ -> processExited _ -> do ret <- io $ tryJust (guard . isEOFError) $ slurpInput processOut processBuffer case ret of Left _ -> processExited -- EOF Right currentBuffer -> do let (datalist, currentBuffer') = readData currentBuffer modify (\s -> s { process = Just (MyProcess processOut processPid currentBuffer') }) if null datalist then return Nothing else return $ Just $ head datalist -- MyData is stored in the reverse order so head is the last MyData from the process slurpInput :: Handle -> String -> IO String slurpInput h buffer = do ready <- hReady h if not ready then return buffer else do char <- hGetChar h slurpInput h (buffer ++ [char]) readData :: String -> ([MyData], String) readData buffer = readData' [] buffer where readData' datalist [] = (datalist, []) readData' datalist buf = case reads buf of [(x, rest)] -> readData' ((head x):datalist) rest -- x is a list and currently it has only one element [] -> if length buf > 5 * maxMyDataDescLength then error "Invalid data from process" else (datalist, buf) -- we probably do not have enough data to read MyData properly _ -> error "Ambiguous parse from process" (I have cleaned a code somewhat, I hope I have not introduced any errors. MyData is encapsulated in a list when printed from a process, this is why is there "head".) The problem is that I do not like this approach. And it does not look nice. For example I am reading byte per byte and appending it to the end. Then the problem is that if process is sending garbage faster then Haskell can consume it Haskell stays in slurpInput function and never gets to readData where it would found out that there is garbage coming in. I could use hGetBufNonBlocking? But it would still not solve garbage problem. So is there some better way to do it? Mitar _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe