11{-# LANGUAGE DeriveGeneric #-}
2+ {-# LANGUAGE LambdaCase #-}
23{-# LANGUAGE NamedFieldPuns #-}
34{-# LANGUAGE OverloadedStrings #-}
45{-# LANGUAGE RecordWildCards #-}
@@ -9,44 +10,24 @@ module Leios.Tracing.Lifecycle (
910 lifecycle ,
1011) where
1112
13+ import Control.Concurrent.Chan (Chan , readChan )
1214import Control.Monad ((<=<) )
13- import Control.Monad.State.Strict (State , execState , gets , modify' )
14- import Data.Aeson (FromJSON (.. ), Value (Object ), withObject , (.:) )
15+ import Control.Monad.IO.Class (liftIO )
16+ import Control.Monad.State.Strict (StateT , execStateT , gets , modify' )
17+ import Data.Aeson (Value (Object ), withObject , (.:) )
1518import Data.Aeson.Types (Parser , parseMaybe )
1619import Data.Function (on )
1720import Data.List (intercalate )
1821import Data.Map.Strict (Map )
1922import Data.Monoid (Sum (.. ))
2023import Data.Set (Set )
2124import Data.Text (Text )
25+ import Leios.Tracing.Util (Minimum (.. ))
2226
2327import qualified Data.Map.Strict as M (elems , fromList , insertWith , restrictKeys , toList , unionWith )
2428import qualified Data.Set as S (map , singleton )
2529import qualified Data.Text as T (unpack )
2630
27- newtype Earliest a = Earliest { getEarliest :: Maybe a }
28- deriving (Show )
29-
30- instance Eq a => Eq (Earliest a ) where
31- Earliest (Just x) == Earliest (Just y) = x == y
32- Earliest Nothing == Earliest Nothing = True
33- _ == _ = False
34-
35- instance Ord a => Ord (Earliest a ) where
36- Earliest (Just x) `compare` Earliest (Just y) = x `compare` y
37- Earliest (Just _) `compare` Earliest Nothing = LT
38- Earliest Nothing `compare` Earliest (Just _) = GT
39- Earliest Nothing `compare` Earliest Nothing = EQ
40-
41- instance Ord a => Semigroup (Earliest a ) where
42- x <> y = if x < y then x else y
43-
44- instance Ord a => Monoid (Earliest a ) where
45- mempty = Earliest Nothing
46-
47- instance FromJSON a => FromJSON (Earliest a ) where
48- parseJSON = fmap Earliest . parseJSON
49-
5031data ItemKey
5132 = ItemKey
5233 { kind :: Text
@@ -56,13 +37,13 @@ data ItemKey
5637
5738data ItemInfo
5839 = ItemInfo
59- { size :: Earliest Int
40+ { size :: Minimum Int
6041 , references :: Sum Int
61- , created :: Earliest Double
62- , toIB :: Earliest Double
63- , toEB :: Earliest Double
64- , toRB :: Earliest Double
65- , inRB :: Earliest Double
42+ , created :: Minimum Double
43+ , toIB :: Minimum Double
44+ , toEB :: Minimum Double
45+ , toRB :: Minimum Double
46+ , inRB :: Minimum Double
6647 , inIBs :: Set Text
6748 , inEBs :: Set Text
6849 }
@@ -102,13 +83,13 @@ toCSV ItemKey{..} ItemInfo{..} =
10283 sep
10384 [ T. unpack kind
10485 , T. unpack item
105- , maybe " NA " show $ getEarliest size
86+ , show size
10687 , show $ getSum references
107- , maybe " NA " show $ getEarliest created
108- , maybe " NA " show $ getEarliest toIB
109- , maybe " NA " show $ getEarliest toEB
110- , maybe " NA " show $ getEarliest toRB
111- , maybe " NA " show $ getEarliest inRB
88+ , show created
89+ , show toIB
90+ , show toEB
91+ , show toRB
92+ , show inRB
11293 ]
11394
11495itemHeader :: String
@@ -133,13 +114,13 @@ parseEvent :: Value -> Parser (ItemKey, ItemInfo, Index)
133114parseEvent =
134115 withObject " TraceEvent" $ \ event ->
135116 do
136- time <- Earliest <$> event .: " time_s"
117+ time <- Minimum <$> event .: " time_s"
137118 message <- event .: " message"
138119 typ <- message .: " type"
139120 ident <- message .: " id"
140121 parseMessage typ ident time $ Object message
141122
142- parseMessage :: Text -> Text -> Earliest Double -> Value -> Parser (ItemKey , ItemInfo , Index )
123+ parseMessage :: Text -> Text -> Minimum Double -> Value -> Parser (ItemKey , ItemInfo , Index )
143124parseMessage " TXGenerated" item created =
144125 withObject " TXGenerated" $ \ message ->
145126 do
@@ -174,7 +155,7 @@ parseMessage _ _ _ =
174155
175156type Index = Map ItemKey ItemInfo
176157
177- tally :: Value -> State Index ()
158+ tally :: Monad m => Value -> StateT Index m ()
178159tally event =
179160 case parseMaybe parseEvent event of
180161 Just (itemKey, itemInfo, updates) ->
@@ -185,7 +166,7 @@ tally event =
185166 modify' $ M. unionWith (<>) updates
186167 Nothing -> pure ()
187168
188- updateInclusions :: Text -> ItemKey -> Set Text -> State Index ()
169+ updateInclusions :: Monad m => Text -> ItemKey -> Set Text -> StateT Index m ()
189170updateInclusions kind itemKey includers =
190171 do
191172 includers' <- gets $ M. elems . (`M.restrictKeys` S. map (ItemKey kind) includers)
@@ -198,24 +179,30 @@ updateInclusions kind itemKey includers =
198179 , toRB = mconcat $ toRB <$> includers'
199180 }
200181
201- updateEBs :: ItemKey -> ItemInfo -> State Index ()
182+ updateEBs :: Monad m => ItemKey -> ItemInfo -> StateT Index m ()
202183updateEBs itemKey = updateInclusions " EB" itemKey . inEBs
203184
204- updateIBs :: ItemKey -> ItemInfo -> State Index ()
185+ updateIBs :: Monad m => ItemKey -> ItemInfo -> StateT Index m ()
205186updateIBs itemKey = updateInclusions " IB" itemKey . inIBs
206187
207- lifecycle :: FilePath -> [ Value ] -> IO ()
188+ lifecycle :: FilePath -> Chan ( Maybe Value ) -> IO ()
208189lifecycle lifecycleFile events =
209- let
210- index =
211- (`execState` mempty ) $
190+ do
191+ let
192+ go =
193+ do
194+ liftIO (readChan events)
195+ >>= \ case
196+ Nothing -> pure ()
197+ Just event -> tally event >> go
198+ index <-
199+ (`execStateT` mempty ) $
212200 do
213201 -- Compute the direct metrics from the traces.
214- mapM_ tally events
202+ go
215203 -- Update arrival in EBs and RBs for IBs.
216204 mapM_ (uncurry updateEBs) =<< gets M. toList
217205 -- Update arrival in EBs and RBs for TXs.
218206 mapM_ (uncurry updateIBs) =<< gets M. toList
219- in
220207 writeFile lifecycleFile . unlines . (itemHeader : ) $
221208 uncurry toCSV <$> M. toList index
0 commit comments