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