1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
module CASS.ServerFunctions where
import FlatCurry.Types (QName)
import FlatCurry.Goodies (progImports)
import Socket(Socket(..),listenOnFresh,sClose,waitForSocketAccept)
import IO(Handle(..),hClose,hFlush,hGetLine,hPutStrLn,hWaitForInput,hWaitForInputs)
import ReadShowTerm(readQTerm,showQTerm)
import System(system,sleep)
import Directory(doesFileExist,getModificationTime)
import Maybe(fromMaybe)
import List(delete)
import Time(ClockTime)
import XML(showXmlDoc,xml)
import Analysis.Logging(debugMessage)
import Analysis.Types
import Analysis.ProgInfo
import CASS.Dependencies
import CASS.Configuration(waitTime)
data WorkerMessage = Task String String | ChangePath String | StopWorker
masterLoop :: [Handle] -> [Handle] -> String -> String
-> [(String,[String])] -> [String] -> IO (Maybe String)
masterLoop _ [] _ _ [] [] = do
debugMessage 2 "Master loop: terminated"
return Nothing
masterLoop _ (b:busyWorker) ananame mainModule [] [] = do
debugMessage 2 "Master loop: waiting for worker result"
inputHandle <- hWaitForInputs (b:busyWorker) waitTime
if inputHandle/=0
then return (Just "No input from any worker received")
else do
let handle = b
input <- hGetLine handle
debugMessage 2 ("Master loop: got message: "++input)
let Task ananame2 moduleName2 = readQTerm input
if ananame==ananame2 && moduleName2==mainModule
then return Nothing
else return (Just "Received analysis does not match requested analysis")
masterLoop idleWorker busyWorker ananame mainModule
modulesToDo@(_:_) [] = do
debugMessage 3 ("Master loop: modules to do: "++(showQTerm modulesToDo))
let modulesToDo2 = filter ((not . null) . snd) modulesToDo
waitList = map fst (filter (null . snd) modulesToDo)
if null waitList
then do
debugMessage 2 "Master loop: waiting for workers to finish"
inputHandle <- hWaitForInputs busyWorker waitTime
if inputHandle<0
then return (Just "No input from any worker received")
else do
let handle = busyWorker !! inputHandle
input <- hGetLine handle
debugMessage 2 ("Master loop: got message: "++input)
let Task ananame2 moduleName2 = readQTerm input
if ananame==ananame2
then do
let modulesToDo3 = reduceDependencies modulesToDo2 [moduleName2]
busyWorker2= deleteIndex inputHandle busyWorker
masterLoop (handle:idleWorker) busyWorker2 ananame
mainModule modulesToDo3 waitList
else
return
(Just "Received analysis does not match requested analysis type")
else masterLoop idleWorker busyWorker ananame mainModule modulesToDo2
waitList
masterLoop (handle:idleWorker) busyWorker ananame mainModule modulesToDo
(modName:waitList) = do
debugMessage 2 "Master loop: worker available, send task to a worker..."
let newTask = showQTerm (Task ananame modName)
hPutStrLn handle newTask
hFlush handle
debugMessage 2 ("Master loop: send message: "++newTask)
masterLoop idleWorker (handle:busyWorker) ananame mainModule
modulesToDo waitList
masterLoop [] busyWorker ananame mainModule modulesToDo
waits@(modName:waitList) = do
debugMessage 2 $ "Waiting for worker to analyze modules: "++show waits
inputHandle <- hWaitForInputs busyWorker waitTime
if inputHandle<0
then return (Just "No input from any worker received")
else do
let handle = busyWorker !! inputHandle
input <- hGetLine handle
debugMessage 2 ("Master loop: got message: "++input)
let Task _ finishedmodule = readQTerm input
newTask = showQTerm (Task ananame modName)
hPutStrLn handle newTask
hFlush handle
debugMessage 2 ("Master loop: send message: "++newTask)
let modulesToDo2 = reduceDependencies modulesToDo [finishedmodule]
masterLoop [] busyWorker ananame mainModule modulesToDo2 waitList
deleteIndex :: Int -> [a] -> [a]
deleteIndex _ [] = []
deleteIndex n (x:xs) | n==0 = xs
| otherwise = x : deleteIndex (n-1) xs
|