2-- Module : Streamly.Internal.Data.Stream.Concurrent.Channel.Consumer
3-- Copyright : (c) 2017 Composewell Technologies
4-- License : BSD-3-Clause
5-- Maintainer : streamly@composewell.com
6-- Stability : experimental
9module Streamly.Internal.Data.Stream.Concurrent.Channel.Consumer
15 -- * Postprocess Hook After Reading
21import Control.Monad.Trans.Control (MonadBaseControl)
22import Control.Monad (when, void)
23import Control.Monad.IO.Class (MonadIO(liftIO))
24import Data.IORef (readIORef)
26import Streamly.Internal.Data.Stream.Concurrent.Channel.Dispatcher
27import Streamly.Internal.Data.Stream.Concurrent.Channel.Type
28import Streamly.Internal.Data.Stream.Channel.Dispatcher
29import Streamly.Internal.Data.Stream.Channel.Types
31-------------------------------------------------------------------------------
32-- Reading from the workers' output queue/buffer
33-------------------------------------------------------------------------------
35{-# INLINE readOutputQChan #-}
36readOutputQChan :: Channel m a -> IO ([ChildEvent a], Int)
37readOutputQChan sv = do
38 let ss = if svarInspectMode sv then Just (svarStats sv) else Nothing
39 in readOutputQRaw (outputQueue sv) ss
41readOutputQBounded :: (MonadIO m, MonadBaseControl IO m) =>
42 Bool -> Channel m a -> m [ChildEvent a]
43readOutputQBounded eagerEval sv = do
44 (list, len) <- liftIO $ readOutputQChan sv
45 -- When there is no output seen we dispatch more workers to help
46 -- out if there is work pending in the work queue.
50 -- send a worker proactively, if needed, even before we start
51 -- processing the output. This may degrade single processor
52 -- perf but improves multi-processor, because of more
60 cnt <- liftIO $ readIORef $ workerCount sv
62 done <- liftIO $ isWorkDone sv
63 when (not done) (pushWorker 0 sv)
65 {-# INLINE blockingRead #-}
67 sendWorkerWait eagerEval sendWorkerDelay (dispatchWorker 0) sv
68 liftIO (fst `fmap` readOutputQChan sv)
70readOutputQPaced :: (MonadIO m, MonadBaseControl IO m) =>
71 Channel m a -> m [ChildEvent a]
72readOutputQPaced sv = do
73 (list, len) <- liftIO $ readOutputQChan sv
77 -- XXX send a worker proactively, if needed, even before we start
78 -- processing the output.
79 void $ dispatchWorkerPaced sv
84 {-# INLINE blockingRead #-}
86 sendWorkerWait False sendWorkerDelayPaced dispatchWorkerPaced sv
87 liftIO (fst `fmap` readOutputQChan sv)
89postProcessPaced :: (MonadIO m, MonadBaseControl IO m) => Channel m a -> m Bool
90postProcessPaced sv = do
91 workersDone <- allThreadsDone (workerThreads sv)
92 -- XXX If during consumption we figure out we are getting delayed then we
93 -- should trigger dispatch there as well. We should try to check on the
94 -- workers after consuming every n item from the buffer?
97 r <- liftIO $ isWorkDone sv
99 void $ dispatchWorkerPaced sv
100 -- Note that we need to guarantee a worker since the work is not
101 -- finished, therefore we cannot just rely on dispatchWorkerPaced
102 -- which may or may not send a worker.
103 noWorker <- allThreadsDone (workerThreads sv)
104 when noWorker $ pushWorker 0 sv
108postProcessBounded :: (MonadIO m, MonadBaseControl IO m) =>
109 Channel m a -> m Bool
110postProcessBounded sv = do
111 workersDone <- allThreadsDone (workerThreads sv)
112 -- There may still be work pending even if there are no workers pending
113 -- because all the workers may return if the outputQueue becomes full. In
114 -- that case send off a worker to kickstart the work again.
116 -- Note that isWorkDone can only be safely checked if all workers are done.
117 -- When some workers are in progress they may have decremented the yield
118 -- Limit and later ending up incrementing it again. If we look at the yield
119 -- limit in that window we may falsely say that it is 0 and therefore we
123 r <- liftIO $ isWorkDone sv
124 -- Note that we need to guarantee a worker, therefore we cannot just
125 -- use dispatchWorker which may or may not send a worker.
126 when (not r) (pushWorker 0 sv)
127 -- XXX do we need to dispatch many here?
128 -- void $ dispatchWorker sv
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list