11{-# LANGUAGE CPP #-}
2+ {-# LANGUAGE GADTs #-}
3+ {-# LANGUAGE LambdaCase #-}
24
35module Cardano.Tracer.Environment
46 ( TracerEnv (.. )
57 , TracerEnvRTView (.. )
8+ , RawMessage (.. )
9+ , InternalMessage (.. )
10+ , Tag (.. )
11+ , CardanoTracerMessage
12+ , onRawMessage
13+ , onInternal
14+ , onUser
15+ , blockUntilShutdown
16+ , dieOnShutdown
17+ , forever'tilShutdown
618 ) where
719
820import Cardano.Logging.Types
21+ import Cardano.Logging.Resources.Types (ResourceStats )
922import Cardano.Tracer.Configuration
1023#if RTVIEW
1124import Cardano.Tracer.Handlers.Notifications.Types
@@ -16,10 +29,13 @@ import Cardano.Tracer.Handlers.State.TraceObjects
1629import Cardano.Tracer.MetaTrace
1730import Cardano.Tracer.Types
1831
32+ import Control.Concurrent (myThreadId )
33+ import Control.Exception (AsyncException (ThreadKilled ), throwTo )
34+ import Control.Concurrent.Chan.Unagi (InChan , OutChan , readChan , tryReadChan , tryRead )
1935import Control.Concurrent.Extra (Lock )
2036import Data.Text (Text )
2137import Data.Text.Lazy.Builder (Builder )
22-
38+ import Data.Kind ( Type )
2339
2440-- | Environment for all functions.
2541data TracerEnv = TracerEnv
@@ -36,6 +52,7 @@ data TracerEnv = TracerEnv
3652 , teRegistry :: ! HandleRegistry
3753 , teStateDir :: ! (Maybe FilePath )
3854 , teMetricsHelp :: ! [(Text , Builder )]
55+ , teInChan :: ! (InChan (CardanoTracerMessage () ))
3956 }
4057
4158#if RTVIEW
@@ -51,3 +68,58 @@ data TracerEnvRTView = TracerEnvRTView
5168#else
5269data TracerEnvRTView = TracerEnvRTView
5370#endif
71+
72+ type CardanoTracerMessage userMsg = RawMessage InternalMessage userMsg
73+
74+ type RawMessage :: Type -> Type -> Type
75+ data RawMessage internal user
76+ = Shutdown
77+ | InternalMessage internal
78+ | UserMessage user
79+
80+ blockUntilShutdown :: OutChan (RawMessage internal user ) -> IO ()
81+ blockUntilShutdown outChan = go where
82+ go :: IO ()
83+ go = readChan outChan >>= \ case
84+ Shutdown -> pure ()
85+ _ -> go
86+
87+ onRawMessage :: (internal -> IO () ) -> (user -> IO () ) -> OutChan (RawMessage internal user ) -> IO ()
88+ onRawMessage internalAction userAction outChan = do
89+ (element, _out) <- tryReadChan outChan
90+ tryRead element >>= \ case
91+ Just (Shutdown ) -> myThreadId >>= (`throwTo` ThreadKilled )
92+ Just (InternalMessage internal) -> internalAction internal
93+ Just (UserMessage user) -> userAction user
94+ Nothing -> pure ()
95+
96+ -- foo :: IO () ->
97+ -- foo action outChan = do
98+ -- (element, _out) <- tryReadChan outChan
99+ -- tryRead element >>= \case
100+ -- Just _ -> action
101+ -- Nothing ->
102+
103+
104+ onInternal :: (internal -> IO () ) -> OutChan (RawMessage internal user ) -> IO ()
105+ onInternal = (`onRawMessage` mempty )
106+
107+ onUser :: (user -> IO () ) -> OutChan (RawMessage internal user ) -> IO ()
108+ onUser = (mempty `onRawMessage` )
109+
110+ data InternalMessage where
111+ ResourceMessage :: Tag ex -> (ex -> IO () ) -> InternalMessage
112+
113+ data Tag a where
114+ TagResource :: Tag (ResourceStats , Trace IO TracerTrace )
115+
116+ dieOnShutdown :: OutChan (RawMessage internal user ) -> IO ()
117+ dieOnShutdown = onRawMessage mempty mempty
118+
119+ forever'tilShutdown :: OutChan (RawMessage internal user ) -> IO () -> IO ()
120+ forever'tilShutdown outChan action = do
121+ (element, _out) <- tryReadChan outChan
122+ tryRead element >>= \ case
123+ Just Shutdown -> pure ()
124+ Just _ -> forever'tilShutdown outChan action
125+ Nothing -> action *> forever'tilShutdown outChan action
0 commit comments