Revision 6222b3a3 src/Ganeti/Query/Server.hs
b/src/Ganeti/Query/Server.hs | ||
---|---|---|
40 | 40 |
import Data.IORef |
41 | 41 |
import qualified Network.Socket as S |
42 | 42 |
import qualified Text.JSON as J |
43 |
import Text.JSON (showJSON, JSValue(..)) |
|
43 |
import Text.JSON (encode, showJSON, JSValue(..))
|
|
44 | 44 |
import System.Info (arch) |
45 | 45 |
|
46 | 46 |
import qualified Ganeti.Constants as C |
... | ... | |
62 | 62 |
import Ganeti.Query.Query |
63 | 63 |
import Ganeti.Query.Filter (makeSimpleFilter) |
64 | 64 |
import Ganeti.Types |
65 |
import Ganeti.Utils (lockFile, exitIfBad) |
|
65 |
import Ganeti.Utils (lockFile, exitIfBad, watchFile)
|
|
66 | 66 |
import qualified Ganeti.Version as Version |
67 | 67 |
|
68 | 68 |
-- | Helper for classic queries. |
... | ... | |
257 | 257 |
else showJSON (False, genericResult id (const "") res)) |
258 | 258 |
$ annotated_results |
259 | 259 |
|
260 |
handleCall _ _ cfg (WaitForJobChange jid fields prev_job prev_log tmout) = do |
|
261 |
let compute_fn = computeJobUpdate cfg jid fields prev_log |
|
262 |
qDir <- queueDir |
|
263 |
-- verify if the job is finalized, and return immediately in this case |
|
264 |
jobresult <- loadJobFromDisk qDir False jid |
|
265 |
case jobresult of |
|
266 |
Ok (job, _) | not (jobFinalized job) -> do |
|
267 |
let jobfile = liveJobFile qDir jid |
|
268 |
answer <- watchFile jobfile (min tmout C.luxiWfjcTimeout) |
|
269 |
(prev_job, JSArray []) compute_fn |
|
270 |
return . Ok $ showJSON answer |
|
271 |
_ -> liftM (Ok . showJSON) compute_fn |
|
272 |
|
|
260 | 273 |
handleCall _ _ _ op = |
261 | 274 |
return . Bad $ |
262 | 275 |
GenericError ("Luxi call '" ++ strOfOp op ++ "' not implemented") |
263 | 276 |
|
264 | 277 |
{-# ANN handleCall "HLint: ignore Too strict if" #-} |
265 | 278 |
|
279 |
-- | Query the status of a job and return the requested fields |
|
280 |
-- and the logs newer than the given log number. |
|
281 |
computeJobUpdate :: ConfigData -> JobId -> [String] -> JSValue |
|
282 |
-> IO (JSValue, JSValue) |
|
283 |
computeJobUpdate cfg jid fields prev_log = do |
|
284 |
let sjid = show $ fromJobId jid |
|
285 |
logDebug $ "Inspecting fields " ++ show fields ++ " of job " ++ sjid |
|
286 |
let fromJSArray (JSArray xs) = xs |
|
287 |
fromJSArray _ = [] |
|
288 |
let logFilter JSNull (JSArray _) = True |
|
289 |
logFilter (JSRational _ n) (JSArray (JSRational _ m:_)) = n < m |
|
290 |
logFilter _ _ = False |
|
291 |
let filterLogs n logs = JSArray (filter (logFilter n) (logs >>= fromJSArray)) |
|
292 |
jobQuery <- handleClassicQuery cfg (Qlang.ItemTypeLuxi Qlang.QRJob) |
|
293 |
[Right . fromIntegral $ fromJobId jid] ("oplog" : fields) False |
|
294 |
let (rfields, rlogs) = case jobQuery of |
|
295 |
Ok (JSArray [JSArray (JSArray logs : answer)]) -> |
|
296 |
(answer, filterLogs prev_log logs) |
|
297 |
_ -> (map (const JSNull) fields, JSArray []) |
|
298 |
logDebug $ "Updates for job " ++ sjid ++ " are " ++ encode (rfields, rlogs) |
|
299 |
return (JSArray rfields, rlogs) |
|
300 |
|
|
266 | 301 |
-- | Given a decoded luxi request, executes it and sends the luxi |
267 | 302 |
-- response back to the client. |
268 | 303 |
handleClientMsg :: MVar () -> JQStatus -> Client -> ConfigReader |
Also available in: Unified diff