{-# LANGUAGE OverloadedStrings #-} module SimpleLocalnetHelper (getSlaveBackend, getSlaveConfBackend, getMasterBackend, getMasterConfBackend, startMasterProcess) where import System.IO import qualified Control.Distributed.Process as DP import qualified Control.Distributed.Process.Node as Node import Control.Distributed.Process.Backend.SimpleLocalnet import qualified Data.ByteString.Char8 as BS import Network.Transport (EndPointAddress(..)) -- | Make a NodeId from "host:port" string. makeNodeId :: String -> DP.NodeId makeNodeId addr = DP.NodeId . EndPointAddress . BS.concat $ [BS.pack addr, ":0"] splitAddr :: String -> (String, String) splitAddr addr = (host, port) where (host, rest) = break (== ':') addr port = tail rest deleteAt :: Int -> [String] -> [String] deleteAt i xs = xs1 ++ xs2 where (xs1, rest) = splitAt i xs xs2 = tail rest getSlaveBackend :: Int -> [String] -> DP.RemoteTable -> IO Backend getSlaveBackend i addrs rtable = do let addr = addrs !! i (host, port) = splitAddr addr backend <- initializeBackend host port rtable return backend getMasterBackend :: Int -> [String] -> DP.RemoteTable -> IO (Backend, [DP.NodeId]) getMasterBackend i addrs rtable = do let addr = addrs !! i (host, port) = splitAddr addr slaves = map makeNodeId $ deleteAt i addrs backend <- initializeBackend host port rtable return (backend, slaves) getClusterConf :: IO [String] getClusterConf = fmap addresses $ readFile "cluster.conf" addresses :: String -> [String] addresses = filter (\x -> head x /= '#') . filter (\x -> not $ null $ filter (\y -> y /= ' ') x) . lines getSlaveConfBackend :: Int -> DP.RemoteTable -> IO Backend getSlaveConfBackend i rtable = do addrs <- getClusterConf getSlaveBackend i addrs rtable getMasterConfBackend :: Int -> DP.RemoteTable -> IO (Backend, [DP.NodeId]) getMasterConfBackend i rtable = do addrs <- getClusterConf getMasterBackend i addrs rtable startMasterProcess :: Backend -> [DP.NodeId] -> (Backend -> [DP.NodeId] -> DP.Process ()) -> IO () startMasterProcess backend slaves process = do node <- newLocalNode backend Node.runProcess node (process backend slaves)