@@ -14,15 +14,16 @@ module Trace.Forward.Utils.TraceObject
14
14
import Control.Concurrent.STM (STM , atomically , retry )
15
15
import Control.Concurrent.STM.TBQueue
16
16
import Control.Concurrent.STM.TVar
17
- import Control.Monad (unless )
17
+ import Control.Monad (unless , (<$!>) )
18
18
import Control.Monad.Extra (whenM )
19
19
import qualified Data.List.NonEmpty as NE
20
20
import Data.Word (Word16 )
21
21
import System.IO
22
22
23
23
import Trace.Forward.Configuration.TraceObject
24
- import Trace.Forward.Protocol.TraceObject.Type
25
24
import qualified Trace.Forward.Protocol.TraceObject.Forwarder as Forwarder
25
+ import Trace.Forward.Protocol.TraceObject.Type
26
+
26
27
27
28
data ForwardSink lo = ForwardSink
28
29
{ forwardQueue :: ! (TVar (TBQueue lo ))
@@ -58,40 +59,57 @@ writeToSink
58
59
-> lo
59
60
-> IO ()
60
61
writeToSink ForwardSink {forwardQueue, disconnectedSize, connectedSize, wasUsed} traceObject = do
61
- q <- readTVarIO forwardQueue
62
- atomically ((,) <$> isFullTBQueue q
63
- <*> isEmptyTBQueue q) >>= \ case
64
- (True , _) -> maybeFlushQueueToStdout q
65
- (_, True ) -> checkIfSinkWasUsed q
66
- (_, _) -> return ()
67
- atomically $ readTVar forwardQueue >>= flip writeTBQueue traceObject
62
+ condToFlush <- atomically $ do
63
+ q <- readTVar forwardQueue
64
+ ((,) <$> isFullTBQueue q
65
+ <*> isEmptyTBQueue q) >>= \ case
66
+ (True , _) -> do
67
+ res <- maybeFlushQueueToStdout q
68
+ q' <- readTVar forwardQueue
69
+ writeTBQueue q' traceObject
70
+ pure res
71
+ (_, True ) -> do
72
+ maybeShrinkQueue q
73
+ q' <- readTVar forwardQueue
74
+ writeTBQueue q' traceObject
75
+ pure Nothing
76
+ (_, _) -> do
77
+ writeTBQueue q traceObject
78
+ pure Nothing
79
+ case condToFlush of
80
+ Nothing -> pure ()
81
+ Just li -> do
82
+ mapM_ print li
83
+ hFlush stdout
68
84
where
69
85
-- The queue is full, but if it's a small queue, we can switch it
70
86
-- to a big one and give a chance not to flush items to stdout yet.
71
87
maybeFlushQueueToStdout q = do
72
- qLen <- atomically $ lengthTBQueue q
88
+ qLen <- lengthTBQueue q
73
89
if fromIntegral qLen == connectedSize
74
- then atomically $ do
90
+ then do
75
91
-- The small queue is full, so we have to switch to a big one and
76
92
-- then flush collected items from the small queue and store them in
77
93
-- a big one.
78
- acceptedItems <- flushTBQueue q
94
+
95
+ acceptedItems <- -- trace ("growQueue disconnected" ++ show disconnectedSize) $
96
+ flushTBQueue q
79
97
switchQueue disconnectedSize
80
98
bigQ <- readTVar forwardQueue
81
99
mapM_ (writeTBQueue bigQ) acceptedItems
100
+ pure Nothing
82
101
else do
83
102
-- The big queue is full, we have to flush it to stdout.
84
- atomically (flushTBQueue q) >>= mapM_ print
85
- hFlush stdout
86
-
87
- checkIfSinkWasUsed q = atomically $
88
- whenM (readTVar wasUsed) $ switchToAnotherQueue q
103
+ Just <$!> flushTBQueue q
89
104
90
- switchToAnotherQueue q = do
91
- qLen <- lengthTBQueue q
92
- if fromIntegral qLen == disconnectedSize
93
- then switchQueue connectedSize
94
- else switchQueue disconnectedSize
105
+ -- if the sink was used and it
106
+ maybeShrinkQueue q = do
107
+ whenM (readTVar wasUsed) $ do
108
+ qLen <- lengthTBQueue q
109
+ if fromIntegral qLen == disconnectedSize
110
+ then -- trace ("shrinkQueue connected " ++ show connectedSize) $
111
+ switchQueue connectedSize
112
+ else pure ()
95
113
96
114
switchQueue size =
97
115
newTBQueue (fromIntegral size) >>= modifyTVar' forwardQueue . const
0 commit comments