
On Tue, Feb 21, 2012 at 5:46 AM, Lyndon Maydwell
Hi Michael, Café.
I'm writing some code using the conduit library and am encountering the following error output (while the program appears to function correctly) when using Data.Conduit.Lazy.
The error given is:
profile_simple_test_data: Control.Monad.Trans.Resource.stateCleanup: There is a bug in the implementation. The mutable state is being accessed after cleanup. Please contact the maintainers.
A reduced code snippet that generates this error is (also attached):
import Control.Monad import System.Environment import Control.Monad.IO.Class (liftIO) import System.IO import Data.Conduit.Lazy import Data.List (sort)
import Data.Conduit
import Prelude hiding (map)
main = getArgs >>= process
process args = mapM_ sorted args
sorted x = runResourceT (lazyConsume $ sourceFeed x) >>= (mapM_ print . id)
sourceFeed :: ResourceIO m => FilePath -> Source m String sourceFeed file = sourceIO (openFile file ReadMode) hClose (\h -> liftIO $ do eof <- hIsEOF h if eof then return IOClosed else fmap IOOpen $ hGetLine h)
when run over any text file.
I may be doing something inconsistent with the correct use of sourceIO or lazyConsume, however, I tried to follow the example at http://www.yesodweb.com/home/snoyberg/blogs/conduit/conduit/source/source.di... as closely as possible.
Is this a bug, or simply an incorrect use of Conduit?
I haven't fully debugged this yet. There's certainly a bug in the implementation of ResourceT, but the sample program is also wrong. You can't pass the result from a call to lazyConsume outside the scope of its ResourceT; the correct way to write sorted would be: sorted x = runResourceT $ lazyConsume (sourceFeed x) >>= mapM_ (liftIO . print) My guess is that this is a fallout from the transition away from mutable variables: lazyConsume no longer has any way of knowing that its ResourceT has already been terminated. Perhaps a simple solution would be to expose a primitive that checks if the ResourceT block has already been finalized. Michael