I'm working with the streaming library but would accept an answer using pipes or conduit.
Say I have
import Streaming (Stream, Of)
import qualified Streaming.Prelude as S
streamChunks :: Int -> Stream (Of Thing) IO ()
streamChunks lastID = do
flip fix 0 $ \go thingID ->
unless (thingID > lastID) $ do
thing <- highLatencyGet thingID
S.yield thing
go (thingID+1)
To reduce latency I'd like to fork highLatencyGet
to retrieve the next Thing
in parallel with processing the previous Thing
in the consumer.
Obviously I could transform my function above creating a new MVar
and forking the next batch before calling yield
, etc.
But I want to know if there is an idiomatic (composable) way to do this, such that it could be packaged in a library and could be used on arbitrary IO Stream
s. Ideally we could configure the prefetch value as well, like:
prefetching :: Int -> Stream (Of a) IO () -> Stream (Of a) IO ()