module Utils
( withLocalNode
, runLocalProcess
)
where
import Control.Concurrent.STM
(atomically, newEmptyTMVar, putTMVar, takeTMVar)
import Control.Distributed.Process
(Process, liftIO)
import Control.Distributed.Process.Node
(LocalNode(..), closeLocalNode, initRemoteTable,
newLocalNode, runProcess)
import Control.Exception
(bracket)
import Network.Transport
(closeTransport)
import Network.Transport.TCP
(createTransport, defaultTCPParameters)
import System.Random
(randomRIO)
withLocalNode :: (LocalNode -> IO a) -> IO a
withLocalNode k = bracket setup cleanup (k . snd)
where
setup = do
transport <- makeTransport
localNode <- newLocalNode transport initRemoteTable
return (transport, localNode)
cleanup (transport, localNode) = do
closeLocalNode localNode
closeTransport transport
makeTransport = do
port <- randomRIO (1024, 65535 :: Int)
etransport <- createTransport "127.0.0.1" (show port)
(\port' -> ("127.0.0.1", port')) defaultTCPParameters
case etransport of
Left _ -> makeTransport
Right transport -> return transport
runLocalProcess :: Process a -> IO a
runLocalProcess process = withLocalNode $ \node -> do
resultVar <- atomically newEmptyTMVar
runProcess node $ do
result <- process
liftIO (atomically (putTMVar resultVar result))
atomically (takeTMVar resultVar)