git.iko.soy/distributed-process
on master help sign in
Add support for logging
commit603646da2655b0f47c7ed77d23b092c3e0dbb2fa authorEdsko de Vries <edsko@edsko.net> dateThu 5 Jul 2012, 16:06 (14 years ago) parente73c666
5 files changed+87−24
distributed-process/distributed-process.cabal+7 distributed-process/src/Control/Distributed/Process.hs+4 distributed-process/src/Control/Distributed/Process/Internal/Primitives.hs+21 distributed-process/src/Control/Distributed/Process/Node.hs+38−21 distributed-process/tests/TestLocalBackend.hs+17−3
distributed-process/distributed-process.cabal+7
@@ -23,6 +23,8 @@ Library
2323 ghc-prim,
2424 network,
2525 network-multicast,
26+ time,
27+ old-locale,
2628 network-transport >= 0.1
2729 Exposed-modules: Control.Distributed.Process,
2830 Control.Distributed.Process.Serializable,
@@ -48,6 +50,8 @@ Test-Suite TestCH
4850 template-haskell,
4951 stm,
5052 ghc-prim,
53+ time,
54+ old-locale,
5155 network-transport >= 0.1
5256 Extensions: ExplicitForAll, ScopedTypeVariables, GeneralizedNewtypeDeriving, FlexibleInstances, UndecidableInstances, MultiParamTypeClasses, DeriveDataTypeable, TemplateHaskell, ExistentialQuantification, RankNTypes, GADTs, ImpredicativeTypes
5357 ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N -fno-warn-unused-do-bind
@@ -69,6 +73,8 @@ Test-Suite TestClosure
6973 ansi-terminal,
7074 template-haskell,
7175 stm,
76+ time,
77+ old-locale,
7278 network-transport >= 0.1
7379 Extensions: ExplicitForAll, ScopedTypeVariables, GeneralizedNewtypeDeriving, FlexibleInstances, UndecidableInstances, MultiParamTypeClasses, DeriveDataTypeable, TemplateHaskell, ExistentialQuantification, RankNTypes, GADTs, ImpredicativeTypes
7480 ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N -fno-warn-unused-do-bind
@@ -89,6 +95,7 @@ Test-Suite TestLocalBackend
8995 ansi-terminal,
9096 template-haskell,
9197 stm,
98+ old-locale,
9299 network-transport >= 0.1
93100 Extensions: ExplicitForAll, ScopedTypeVariables, GeneralizedNewtypeDeriving, FlexibleInstances, UndecidableInstances, MultiParamTypeClasses, DeriveDataTypeable, TemplateHaskell, ExistentialQuantification, RankNTypes, GADTs, ImpredicativeTypes
94101 ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N -fno-warn-unused-do-bind
distributed-process/src/Control/Distributed/Process.hs+4
@@ -64,6 +64,8 @@ module Control.Distributed.Process
6464 , Static
6565 , unClosure
6666 , RemoteTable
67+ -- * Logging
68+ , say
6769 -- * Registry
6870 , register
6971 , unregister
@@ -155,6 +157,8 @@ import Control.Distributed.Process.Internal.Primitives
155157 , monitorNode
156158 , monitorPort
157159 , unmonitor
160+ -- Logging
161+ , say
158162 -- Registry
159163 , register
160164 , unregister
distributed-process/src/Control/Distributed/Process/Internal/Primitives.hs+21
@@ -29,6 +29,8 @@ module Control.Distributed.Process.Internal.Primitives
2929 , unlink
3030 , monitor
3131 , unmonitor
32+ -- * Logging
33+ , say
3234 -- * Registry
3335 , register
3436 , unregister
@@ -53,6 +55,9 @@ module Control.Distributed.Process.Internal.Primitives
5355import Prelude hiding (catch)
5456import Data.Binary (decode)
5557import Data.Typeable (Typeable,)
58+import Data.Time.Clock (getCurrentTime)
59+import Data.Time.Format (formatTime)
60+import System.Locale (defaultTimeLocale)
5661import Control.Monad.Reader (ask)
5762import Control.Monad.IO.Class (MonadIO, liftIO)
5863import Control.Applicative ((<$>))
@@ -362,6 +367,22 @@ unlinkPortAsync :: SendPort a -> Process ()
362367unlinkPortAsync (SendPort cid) =
363368 sendCtrlMsg Nothing . Unlink $ SendPortIdentifier cid
364369
370+--------------------------------------------------------------------------------
371+-- Logging --
372+--------------------------------------------------------------------------------
373+
374+-- | Log a string
375+--
376+-- @say message@ sends a message (time, pid of the current process, message)
377+-- to the process registered as 'logger'. By default, this process simply
378+-- sends the string to 'stderr'. Individual Cloud Haskell backends might
379+-- replace this with a different logger process, however.
380+say :: String -> Process ()
381+say string = do
382+ now <- liftIO getCurrentTime
383+ us <- getSelfPid
384+ nsend "logger" (formatTime defaultTimeLocale "%c" now, us, string)
385+
365386--------------------------------------------------------------------------------
366387-- Registry --
367388--------------------------------------------------------------------------------
distributed-process/src/Control/Distributed/Process/Node.hs+38−21
@@ -9,7 +9,7 @@ module Control.Distributed.Process.Node
99 ) where
1010
1111import Prelude hiding (catch)
12−import System.IO (fixIO)
12+import System.IO (fixIO, hPutStrLn, stderr)
1313import qualified Data.ByteString.Lazy as BSL (fromChunks)
1414import Data.Binary (decode)
1515import Data.Map (Map)
@@ -120,6 +120,7 @@ import Control.Distributed.Process.Internal.Closure
120120 , resolveClosure
121121 )
122122import Control.Distributed.Process.Internal.Node (runLocalProcess)
123+import Control.Distributed.Process.Internal.Primitives (expect, register)
123124
124125--------------------------------------------------------------------------------
125126-- Initialization --
@@ -131,26 +132,42 @@ import Control.Distributed.Process.Internal.Node (runLocalProcess)
131132-- to do.
132133newLocalNode :: NT.Transport -> RemoteTable -> IO LocalNode
133134newLocalNode transport rtable = do
134− mEndPoint <- NT.newEndPoint transport
135− case mEndPoint of
136− Left ex -> throwIO ex
137− Right endPoint -> do
138− unq <- randomIO
139− state <- newMVar LocalNodeState
140− { _localProcesses = Map.empty
141− , _localPidCounter = 0
142− , _localPidUnique = unq
143− }
144− ctrlChan <- newChan
145− let node = LocalNode { localNodeId = NodeId $ NT.address endPoint
146− , localEndPoint = endPoint
147− , localState = state
148− , localCtrlChan = ctrlChan
149− , remoteTable = rtable
150− }
151− void . forkIO $ runNodeController node
152− void . forkIO $ handleIncomingMessages node
153− return node
135+ mEndPoint <- NT.newEndPoint transport
136+ case mEndPoint of
137+ Left ex -> throwIO ex
138+ Right endPoint -> do
139+ localNode <- createBareLocalNode endPoint rtable
140+ startServiceProcesses localNode
141+ return localNode
142+
143+-- | Create a new local node (without any service processes running)
144+createBareLocalNode :: NT.EndPoint -> RemoteTable -> IO LocalNode
145+createBareLocalNode endPoint rtable = do
146+ unq <- randomIO
147+ state <- newMVar LocalNodeState
148+ { _localProcesses = Map.empty
149+ , _localPidCounter = 0
150+ , _localPidUnique = unq
151+ }
152+ ctrlChan <- newChan
153+ let node = LocalNode { localNodeId = NodeId $ NT.address endPoint
154+ , localEndPoint = endPoint
155+ , localState = state
156+ , localCtrlChan = ctrlChan
157+ , remoteTable = rtable
158+ }
159+ void . forkIO $ runNodeController node
160+ void . forkIO $ handleIncomingMessages node
161+ return node
162+
163+-- | Start and register the service processes on a node
164+-- (for now, this is only the logger)
165+startServiceProcesses :: LocalNode -> IO ()
166+startServiceProcesses node = do
167+ logger <- forkProcess node . forever $ do
168+ (time, pid, string) <- expect :: Process (String, ProcessId, String)
169+ liftIO . hPutStrLn stderr $ time ++ " " ++ show pid ++ ": " ++ string
170+ runProcess node $ register "logger" logger
154171
155172-- | Force-close a local node
156173--
distributed-process/tests/TestLocalBackend.hs+17−3
@@ -1,18 +1,32 @@
11import System.Environment (getArgs, getProgName)
2−import Control.Distributed.Process.Node (initRemoteTable)
2+import Control.Distributed.Process (say)
3+import Control.Distributed.Process.Node
4+ ( initRemoteTable
5+ , forkProcess
6+ , runProcess
7+ )
38import Control.Distributed.Process.Backend.Local
49import Control.Concurrent (threadDelay)
5−import Control.Monad (replicateM)
10+import Control.Monad (forever)
11+import Control.Monad.IO.Class (liftIO)
612
713server :: LocalBackend -> IO ()
814server backend = do
915 node <- newLocalNode backend
16+ runProcess node $
17+ say "this is the server"
18+ {-
1019 nodes <- findPeers backend 1000000
1120 print nodes
21+ -}
22+ threadDelay 30000000
1223
1324client :: LocalBackend -> IO ()
1425client backend = do
15− [node1, node2] <- replicateM 2 $ newLocalNode backend
26+ node <- newLocalNode backend
27+ forkProcess node . forever $ do
28+ say "this is a client node1"
29+ liftIO $ threadDelay 5000000
1630 threadDelay 30000000
1731
1832main :: IO ()