streamly-0.11.0: src/Streamly/Data/Stream/Prelude.hs
-- |
-- Module : Streamly.Data.Stream.Prelude
-- Copyright : (c) 2022 Composewell Technologies
-- License : BSD-3-Clause
-- Maintainer : streamly@composewell.com
-- Stability : experimental
-- Portability : GHC
--
-- For upgrading to streamly-0.9.0+ please read the
-- <https://github.com/composewell/streamly/blob/streamly-0.10.0/docs/User/Project/Upgrading-0.8-to-0.9.md Streamly-0.9.0 upgrade guide>.
-- Also, see the "Streamly.Data.Stream.MkType" module for direct replacement of
-- stream types that have been removed in 0.9.0.
--
-- All Stream related combinators including the streamly-core
-- "Streamly.Data.Stream" module, concurrency, time and lifted
-- exception operations. For more pre-release operations also see
-- "Streamly.Internal.Data.Stream.Prelude" module.
--
module Streamly.Data.Stream.Prelude
(
-- * "Streamly.Data.Stream"
-- | All "Streamly.Data.Stream" combinators are re-exported via this
-- module. For more pre-release combinators also see
-- "Streamly.Internal.Data.Stream" module.
module Streamly.Data.Stream
-- * Concurrent Operations
-- $concurrency
-- ** Types
, MonadAsync
-- ** Configuration
, Config
-- *** Limits
, maxThreads
, maxBuffer
-- *** Rate Control
, Rate(..)
, rate
, avgRate
, minRate
, maxRate
, constRate
-- *** Stop behavior
, StopWhen (..)
, stopWhen
-- *** Scheduling behavior
, eager
, ordered
, interleaved
-- *** Resource management
, useAcquire
, clearAcquire
-- *** Diagnostics
, inspect
-- ** Combinators
-- | Stream combinators using a concurrent channel.
-- *** Evaluate
-- | Evaluate a stream as a whole concurrently with respect to the consumer
-- of the stream.
, parBuffered
-- *** Generate
-- | Generate a stream by evaluating multiple actions concurrently.
, parRepeatM
, parReplicateM
, fromCallback
-- *** Map
-- | Map actions on a stream such that the mapped actions are evaluated
-- concurrently with each other.
, parMapM
, parSequence
-- *** Combine two
-- | Combine two streams such that each stream as a whole is evaluated
-- concurrently with respect to the other stream as well as the consumer of
-- the resulting stream.
, parZipWithM
, parZipWith
, parMergeByM
, parMergeBy
-- *** List of streams
-- | Shares a single channel across many streams.
, parList
-- , zipWithM
-- , zipWith
-- *** Stream of streams
-- **** Apply
, parCrossApply
-- **** Concat
-- | Shares a single channel across many streams.
, parConcat
, parConcatMap
-- **** ConcatIterate
, parConcatIterate
-- *** Observation
, parTapCount
-- * Time Related
-- ** Timers
, interject
-- ** Trimming
, takeInterval
, dropInterval
-- ** Chunking
, intervalsOf
-- ** Sampling
, sampleIntervalEnd
, sampleIntervalStart
, sampleBurstEnd
, sampleBurstStart
-- * Lifted Exceptions
, after
, bracket
-- , bracket3
, finally
-- ** Deprecated
, tapCount
, parEval
, parApply
)
where
import Streamly.Data.Stream
import Streamly.Internal.Data.Stream.Prelude
-- $concurrency
--
-- == Channels
--
-- At a lower level, concurrency is implemented using channels that support
-- concurrent evaluation of streams. We create a channel, and add one or more
-- streams to it. The channel evaluates multiple streams concurrently and then
-- generates a single output stream from the results. How the streams are
-- combined depends on the configuration of the channel.
--
-- == Primitives
--
-- There are only a few fundamental abstractions for concurrency, 'parBuffered',
-- 'parConcatMap', and 'parConcatIterate', all concurrency combinators can be
-- expressed in terms of these.
--
-- 'parBuffered' evaluates a stream as a whole asynchronously with respect to
-- the consumer of the stream. A worker thread evaluates multiple elements of
-- the stream ahead of time and buffers the results; the consumer of the stream
-- runs in another thread consuming the elements from the buffer, thus
-- decoupling the production and consumption of the stream. 'parBuffered' can be
-- used to run different stages of a pipeline concurrently.
--
-- 'parConcatMap' is used to evaluate multiple actions in a stream concurrently
-- with respect to each other or to evaluate multiple streams concurrently and
-- combine the results. A stream generator function is mapped to the input
-- stream and all the generated streams are then evaluated concurrently, and
-- the results are combined.
--
-- 'parConcatIterate' is like 'parConcatMap' but iterates a stream generator
-- function recursively over the stream. This can be used to traverse trees or
-- graphs.
--
-- == Configuration
--
-- Concurrent combinators take a 'Config' argument which controls the
-- concurrent behavior. For example, maximum number of threads to be used
-- ('maxThreads') or the maxmimum size of the buffer ('maxBuffer'), or how the
-- streams are scheduled with respect to each other ('interleaved'), or how the
-- results are consumed ('ordered').
--
-- Configuration is specified as @Config -> Config@ modifier functions that can
-- be composed together using function composition. For example, to specify the
-- maximum threads we can use @parConcatMap (maxThreads 10)@ if we also want to
-- specify the maximum buffer we can compose the two options @parConcatMap
-- (maxThreads 10 . maxBuffer 100)@. To use default configuration use 'id' as
-- the config modifier e.g. @parConcatMap id@.
--
-- See the @Configuration@ section and individual configuration options'
-- documentation for the default behavior and default values of configuration
-- parameters.
--
-- == Scheduling
--
-- The most important configuration option is to control whether the output of
-- the concurrent execution is consumed in the same order as the corresponding
-- actions in the input stream or as soon as they arrive. The default is the
-- latter, however, we can enforce the original order by using the 'ordered'
-- option.
--
-- Another important option controls whether the number of worker threads are
-- automatically increased and decreased based on the consumption rate or
-- threads are started as aggresively as possible until the 'maxThreads' or
-- 'maxBuffer' limits are hit. The default is the former. However, the 'eager'
-- option can be enabled to use the latter behavior. When 'eager' is on, even
-- if the stream consumer thread blocks it does not make any impact on the
-- scheduling of the available tasks.
--
-- == Combinators
--
-- Using the few fundamental concurrency primitives we can implement all the
-- usual streaming combinators with concurrent behavior. Combinators like
-- 'unfoldrM', 'iterateM' that are inherently serial can be evaluated
-- concurrently with respect to the consumer pipeline using 'parBuffered'.
-- Combinators like 'zipWithM', 'mergeByM' can also use 'parBuffered' on the input
-- streams to evaluate them concurrently before combining.
--
-- Combinators like 'repeatM', 'replicateM', 'fromListM', 'sequence', 'mapM' in
-- which all actions are independent of each other can be made concurrent using
-- the 'parConcatMap' operation.
--
-- A concurrent 'repeatM' repeats an action using multiple concurrent
-- executions of the action. Similarly, a concurrent 'mapM' performs the mapped
-- action in independent threads.
--
-- Some common concurrent combinators are provided in this module.