{-# LANGUAGE ScopedTypeVariables, DeriveDataTypeable #-} module Main where import Transient.Move import Transient.Logged import Transient.Base import Network import Control.Applicative import Control.Monad.IO.Class import System.Environment import System.IO.Unsafe import Data.Monoid import System.IO import Control.Monad import Data.Maybe import Control.Exception import Control.Concurrent (threadDelay) import Data.Typeable import Control.Concurrent.STM import Data.IORef -- some tests for distributed computing --main= do -- let port1 = PortNumber 2000 -- port2 = PortNumber 2001 -- -- -- keep $ do -- conn port1 port1 <|> conn port2 port1 -- -- examples' host port2 -- where -- host= "localhost" ---- delay = liftIO $ threadDelay 1000000 -- conn p p'= connect host p host p' -- -- -- -- -- --test = do -- args <- getArgs -- let ports= [("localhost",PortNumber 2000), ("localhost",PortNumber 2001)] -- -- let [(_,port1), (_,port2)]= if null args then ports else reverse ports -- print [port1, port2] -- let local= "localhost" -- beamInit port1 $ do -- logged $ option "call" "call" -- callTo local port2 (liftIO $ print "HOLA") -- <|> callTo local port2(liftIO $ print "HELLO") -- to be executed with two or more nodes main = do args <- getArgs if length args < 2 then do putStrLn "The program need at least two parameters: localHost localPort remoteHost RemotePort" putStrLn "Start one node alone. The rest, connected to this node." return () else keep $ do let localHost= head args localPort= PortNumber . fromInteger . read $ args !! 1 (remoteHost,remotePort) = if length args >=4 then(args !! 2, PortNumber . fromInteger . read $ args !! 3) else (localHost,localPort) connect localHost localPort remoteHost remotePort examples examples = do logged $ option "main" "to see the menu" <|> return "" r <-logged $ option "move" "move to another node" <|> option "call" "call a function in another node" <|> option "chat" "chat" <|> option "netev" "events propagating trough the network" case r of "call" -> callExample "move" -> moveExample "chat" -> chat "netev" -> networkEvents data Environ= Environ (IORef String) deriving Typeable callExample = do nodes <- logged getNodes let Node host port _= head $ tail nodes logged $ putStrLnhp port "asking for the remote data" s <- callTo host port $ do putStrLnhp port "remote callTo request" liftIO $ readIORef environ liftIO $ putStrLn $ "resp=" ++ show s environ= unsafePerformIO $ newIORef "Not Changed" moveExample = do nodes <- logged getNodes let Node host port _= head $ tail nodes putStrLnhp port "enter a string. It will be inserted in the other node by a migrating program" name <- logged $ input (const True) beamTo host port putStrLnhp port "moved!" putStrLnhp port $ "inserting "++ name ++" as new data in this node" liftIO $ writeIORef environ name return() chat :: TransIO () chat = do name <- logged $ do liftIO $ putStrLn "Name?" ; input (const True) text <- logged $ waitEvents $ putStr ">" >> hFlush stdout >> getLine' (const True) let line= name ++": "++ text clustered $ liftIO $ putStrLn line networkEvents = do nodes <- logged getNodes let Node rh rp _= head $ tail nodes logged $ do putStrLnhp rp "callTo is not a simole remote call. it stablish a connection" putStrLnhp rp "between transient processes in different nodes" putStrLnhp rp "in this example, events are piped back from a remote node to the local node" r <- callTo rh rp $ do option "fire" "fire event" return "event fired" putStrLnhp rp $ r ++ " in remote node" putStrLnhp p msg= liftIO $ putStr (show p) >> putStr " ->" >> putStrLn msg --call host port proc params= do -- port <- getPort -- listen port <|> return -- parms <- logged $ return params -- callTo host port proc parms -- close -- --distribute proc= do -- case dataFor proc -- Nothing -> proc -- Just dataproc -> do -- (h,p) <- bestNode dataproc -- callTo h p proc -- --bestNode dataproc= -- nodes <- getNodes -- (h,p) <- bestMatch dataproc nodes <- user defined -- --bestMatch (DataProc nodesAccesed cpuLoad resourcesNeeded) nodes= do -- nodesAccesed: node, response -- --bestMove= do -- thisproc <- gets myProc -- case dataFor thisproc -- Nothing -> return () -- Just dataproc -> do -- (h,p) <- bestNode dataproc -- moveTo h p -- -- --inNetwork= do -- p <- getPort -- listen p <|> return ()