@@ -378,49 +378,30 @@ x |&. f = f |$. x
378-- ParallelT
378-- ParallelT
379------------------------------------------------------------------------------
379------------------------------------------------------------------------------
381−-- | Async composition with simultaneous traversal of all streams.
381+-- | Async composition with strict concurrent execution of all streams.
383−-- The Semigroup instance of 'ParallelT' concurrently /merges/ two streams,
383+-- The 'Semigroup' instance of 'ParallelT' executes both the streams
384−-- running both strictly concurrently and yielding elements from both streams
384+-- concurrently without any delay or without waiting for the consumer demand
385−-- as they arrive. When multiple streams are combined using 'ParallelT' each
385+-- and /merges/ the results as they arrive. If the consumer does not consume
386−-- one is evaluated in its own thread and the results produced are presented in
386+-- the results, they are buffered upto a configured maximum, controlled by the
387−-- the combined stream on a first come first serve basis.
387+-- 'maxBuffer' primitive. If the buffer becomes full the concurrent tasks will
388−--
388+-- block until there is space in the buffer.
389−-- 'AsyncT' and 'WAsyncT' are /concurrent lookahead streams/ each with a
389+--
390−-- specific type of consumption pattern (depth first or breadth first). Since
391−-- they are lookahead, they may introduce certain default latency in starting
392−-- more concurrent tasks for efficiency reasons or may put a default limitation
393−-- on the resource consumption (e.g. number of concurrent threads for
394−-- lookahead). If we look at the implementation detail, they both can share a
395−-- pool of worker threads to evaluate the streams in the desired pattern and at
396−-- the desired rate. However, 'ParallelT' uses a separate runtime thread to
397−-- evaluate each stream.
399−-- 'WAsyncT' is similar to 'ParallelT', as both of them evaluate the
400−-- constituent streams fairly in a round robin fashion.
390+-- Both 'WAsyncT' and 'ParallelT', evaluate the constituent streams fairly in a
401−-- However, the key difference is that 'WAsyncT' is lazy or pull driven
391+-- round robin fashion. The key difference is that 'WAsyncT' might wait for the
402−-- whereas 'ParallelT' is strict or push driven. 'ParallelT' immediately
392+-- consumer demand before it executes the tasks whereas 'ParallelT' starts
403−-- starts concurrent evaluation of both the streams (in separate threads) and
393+-- executing all the tasks immediately without waiting for the consumer demand.
404−-- later picks the results whereas 'WAsyncT' may wait for a certain latency
394+-- For 'WAsyncT' the 'maxThreads' limit applies whereas for 'ParallelT' it does
405−-- threshold before initiating concurrent evaluation of the next stream. The
395+-- not apply. In other words, 'WAsyncT' can be lazy whereas 'ParallelT' is
406−-- concurrent scheduling of the next stream or the degree of concurrency is
396+-- strict.
407−-- driven by the feedback from the consumer. In case of 'ParallelT' each stream
397+--
408−-- is evaluated in a separate thread and results are /pushed/ to a shared
409−-- output buffer, the evaluation rate is controlled by blocking when the buffer
412−-- Concurrent lookahead streams are generally more efficient than
413−-- 'ParallelT' and can work pretty efficiently even for smaller tasks because
414−-- they do not necessarily use a separate thread for each task. So they should
415−-- be preferred over 'ParallelT' especially when efficiency is a concern and
416−-- simultaneous strict evaluation is not a requirement. 'ParallelT' is useful
417−-- for cases when the streams are required to be evaluated simultaneously
398+-- 'ParallelT' is useful for cases when the streams are required to be
418−-- irrespective of how the consumer consumes them e.g. when we want to race
399+-- evaluated simultaneously irrespective of how the consumer consumes them e.g.
419−-- two tasks and want to start both strictly at the same time or if we have
400+-- when we want to race two tasks and want to start both strictly at the same
420−-- timers in the parallel tasks and our results depend on the timers being
401+-- time or if we have timers in the parallel tasks and our results depend on
421−-- started at the same time. We can say that 'ParallelT' is almost the same
402+-- the timers being started at the same time. If we do not have such
422−-- (modulo some implementation differences) as 'WAsyncT' when the latter is
403+-- requirements then 'AsyncT' or 'AheadT' are recommended as they can be more
423−-- used with unlimited lookahead and zero latency in initiating lookahead.
404+-- efficient than 'ParallelT'.
426-- main = ('toList' . 'parallely' $ (fromFoldable [1,2]) \<> (fromFoldable [3,4])) >>= print
407-- main = ('toList' . 'parallely' $ (fromFoldable [1,2]) \<> (fromFoldable [3,4])) >>= print
@@ -462,7 +443,9 @@ x |&. f = f |$. x
462-- Note that parallel composition can only combine a finite number of
443-- Note that parallel composition can only combine a finite number of
463-- streams as it needs to retain state for each unfinished stream.
444-- streams as it needs to retain state for each unfinished stream.
465−-- @since 0.1.0
446+-- /Since: 0.7.0 (maxBuffer applies to ParallelT streams)/
466newtype ParallelT m a = ParallelT {getParallelT :: Stream m a}
449newtype ParallelT m a = ParallelT {getParallelT :: Stream m a}
467 deriving (MonadTrans)
450 deriving (MonadTrans)