@@ -0,0 +1,41 @@
1+module TypedWorkPushing where
2+
3+import Control.Monad
4+import Control.Distributed.Process
5+import Control.Distributed.Process.Closure
6+import PrimeFactors
7+
8+slave :: SendPort Integer -> ReceivePort Integer -> Process ()
9+slave results todo = forever $ do
10+ n <- receiveChan todo
11+ sendChan results (numPrimeFactors n)
12+
13+sdictInteger :: SerializableDict Integer
14+sdictInteger = SerializableDict
15+
16+remotable ['slave, 'sdictInteger]
17+
18+-- | Wait for n integers and sum them all up
19+sumIntegers :: ReceivePort Integer -> Int -> Process Integer
20+sumIntegers rport = go 0
21+ where
22+ go :: Integer -> Int -> Process Integer
23+ go !acc 0 = return acc
24+ go !acc n = do
25+ m <- receiveChan rport
26+ go (acc + m) (n - 1)
27+
28+master :: Integer -> [NodeId] -> Process Integer
29+master n slaves = do
30+ (sport, rport) <- newChan
31+
32+ -- Start slave processes
33+ slaveProcesses <- forM slaves $ \nid ->
34+ spawnChannel $(mkStatic 'sdictInteger) nid ($(mkClosure 'slave) sport)
35+
36+ -- Distribute 1 .. n amongst the slave processes
37+ spawnLocal $ forM_ (zip [1 .. n] (cycle slaveProcesses)) $
38+ \(m, them) -> sendChan them m
39+
40+ -- Wait for the result
41+ sumIntegers rport (fromIntegral n)