module Main where
import Control.Concurrent (threadDelay)
import Control.Distributed.Process hiding (call)
import Control.Distributed.Process.Node
import Control.Distributed.Process.Platform.Async.AsyncChan hiding (worker)
import qualified Control.Distributed.Process.Platform.Async.AsyncChan as C (worker)
import Control.Distributed.Process.Platform.ManagedProcess hiding
(call, callAsync, shutdown, runProcess)
import qualified Control.Distributed.Process.Platform.ManagedProcess as P (call, shutdown)
import Control.Distributed.Process.Platform.Time
import Control.Distributed.Process.Platform.Timer
import Control.Exception (SomeException)
import Network.Transport.TCP (createTransportExposeInternals, defaultTCPParameters)
import Prelude hiding (catch)
import Data.Time.Clock (getCurrentTime)
import Data.Time.Format (formatTime)
import System.Locale (defaultTimeLocale)
{-# INLINE forever' #-}
forever' :: Monad m => m a -> m b
forever' a = let a' = a >> a' in a'
main :: IO ()
main = do
node <- startLocalNode
runProcess node $ doWork True False
runProcess node $ doWork False False
-- runProcess node $ doWork True False
-- runProcess node worker
-- runProcess node $ do
-- sleep $ seconds 10
-- say "done...."
threadDelay $ (1*1000000)
closeLocalNode node
return ()
worker :: Process ()
worker = do
server <- startGenServer
_ <- monitor server
mapM_ (\(n :: Int) -> (P.call server ("bar" ++ (show n))) :: Process String) [1..800]
-- sleep $ seconds 3
-- P.shutdown server
-- receiveWait [ match (\(ProcessMonitorNotification _ _ _) -> return ()) ]
say "server is idle now..."
sleep $ seconds 5
doWork :: Bool -> Bool -> Process ()
doWork useAsync killServer =
let call' = case useAsync of
True -> callAsync
False -> call
in do
server <- spawnLocal $ forever' $ do
receiveWait [ match (\(pid, _ :: String) -> send pid ()) ]
mapM_ (\(n :: Int) -> (call' server (show n)) :: Process () ) [1..800]
sleep $ seconds 4
say "done"
case killServer of
True -> kill server "stop"
False -> return ()
sleep $ seconds 1
startLocalNode :: IO LocalNode
startLocalNode = do
Right (transport,_) <- createTransportExposeInternals "127.0.0.1"
"8081"
defaultTCPParameters
node <- newLocalNode transport initRemoteTable
return node
callAsync :: ProcessId -> String -> Process ()
callAsync pid s = do
asyncRef <- async $ AsyncTask $ call pid s
(AsyncDone _) <- wait asyncRef
return ()
call :: ProcessId -> String -> Process ()
call pid s = do
self <- getSelfPid
send pid (self, s)
expect :: Process ()
startGenServer :: Process ProcessId
startGenServer = do
sid <- spawnLocal $ do
catch (start () (statelessInit Infinity) serverDefinition >> return ())
(\(e :: SomeException) -> say $ "failed with " ++ (show e))
return sid
serverDefinition :: ProcessDefinition ()
serverDefinition =
statelessProcess {
apiHandlers = [
handleCall_ (\(s :: String) -> return s)
, handleCast (\s (_ :: String) -> continue s)
]
}