@@ -0,0 +1,66 @@
1+import System.Environment (getArgs)
2+import Control.Monad
3+import Control.Distributed.Process
4+import Control.Distributed.Process.Closure
5+
6+#ifdef USE_SIMPLELOCALNET
7+import Control.Distributed.Process.Node (initRemoteTable)
8+import Control.Distributed.Process.Backend.SimpleLocalnet
9+#endif
10+
11+--------------------------------------------------------------------------------
12+-- Backend agnostic code --
13+--------------------------------------------------------------------------------
14+
15+fib :: Integer -> Integer
16+fib = go (0, 1)
17+ where
18+ go (!a, !b) !n | n == 0 = a
19+ | otherwise = go (b, a + b) (n - 1)
20+
21+slave :: () -> Process ()
22+slave () = forever $ do
23+ (pid, n) <- expect
24+ send pid (fib n)
25+
26+remotable ['slave]
27+
28+master :: Integer -> [NodeId] -> Process Integer
29+master n slaves = do
30+ us <- getSelfPid
31+
32+ -- Start processes on the slaves that compute Fibonacci numbers
33+ slaveProcesses <- forM slaves $ flip spawn ($(mkClosure 'slave) ())
34+
35+ -- Distribute 1 .. n amongst the slave processes
36+ forM_ (zip [1 .. n] (cycle slaveProcesses)) $ \(m, them) ->
37+ send them (us, m)
38+
39+ -- Wait for the result
40+ partials <- replicateM (fromInteger n) (expect :: Process Integer)
41+
42+ -- And return the sum
43+ return (sum partials)
44+
45+rtable :: RemoteTable
46+rtable = __remoteTable initRemoteTable
47+
48+--------------------------------------------------------------------------------
49+-- Using the SimpleLocalnet backend --
50+--------------------------------------------------------------------------------
51+
52+#ifdef USE_SIMPLELOCALNET
53+main :: IO ()
54+main = do
55+ args <- getArgs
56+
57+ case args of
58+ ["master", host, port, n] -> do
59+ backend <- initializeBackend host port rtable
60+ startMaster backend $ \slaves -> do
61+ result <- master (read n) slaves
62+ liftIO $ print result
63+ ["slave", host, port] -> do
64+ backend <- initializeBackend host port rtable
65+ startSlave backend
66+#endif -- USE_SIMPLELOCALNET