I'm trying to read a group of up to 50 items from a pipe and process them in an IO action all at once. (The use case for this is I'm trying to insert data into a database and I want to do an entire batch inside one transaction because it is vastly more efficient). Here is a simplified version of what I've got so far:
type ExampleType = Int
doSomething :: [ExampleType] -> IO ()
doSomething = undefined
inGroupsOf50 :: Monad m => Producer ExampleType m () -> m ()
inGroupsOf50 input =
runEffect $ input >-> loop
where loop = do entries <- replicateM 50 await
lift $ doSomething entries --Insert a bunch all in one transaction
loop
The problem is as far as I can tell, unless the number of items to insert happens to divide by 50, I'm going to miss some. What I really want instead of replicateM 50 await
is something that gives me up to 50 items or fewer if the input ends but I can't quite figure out how to write that.
I've been thinking that pipes-parse might be the right library to be looking at. draw
looks to have a promising signature... but so far all the bits aren't fitting together in my head. I have a producer
, I'm writing a consumer
and I don't really get how that relates to the concept of a parser
.