Statistics
| Branch: | Tag: | Revision:

root / src / Ganeti / Jobs.hs @ ecff332f

History | View | Annotate | Download (3.3 kB)

1 369671f4 Dato Simó
{-| Generic code to work with jobs, e.g. submit jobs and check their status.
2 13b6cb3f Iustin Pop
3 13b6cb3f Iustin Pop
-}
4 13b6cb3f Iustin Pop
5 13b6cb3f Iustin Pop
{-
6 13b6cb3f Iustin Pop
7 ad0e078e Iustin Pop
Copyright (C) 2009, 2010, 2011, 2012 Google Inc.
8 13b6cb3f Iustin Pop
9 13b6cb3f Iustin Pop
This program is free software; you can redistribute it and/or modify
10 13b6cb3f Iustin Pop
it under the terms of the GNU General Public License as published by
11 13b6cb3f Iustin Pop
the Free Software Foundation; either version 2 of the License, or
12 13b6cb3f Iustin Pop
(at your option) any later version.
13 13b6cb3f Iustin Pop
14 13b6cb3f Iustin Pop
This program is distributed in the hope that it will be useful, but
15 13b6cb3f Iustin Pop
WITHOUT ANY WARRANTY; without even the implied warranty of
16 13b6cb3f Iustin Pop
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 13b6cb3f Iustin Pop
General Public License for more details.
18 13b6cb3f Iustin Pop
19 13b6cb3f Iustin Pop
You should have received a copy of the GNU General Public License
20 13b6cb3f Iustin Pop
along with this program; if not, write to the Free Software
21 13b6cb3f Iustin Pop
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 13b6cb3f Iustin Pop
02110-1301, USA.
23 13b6cb3f Iustin Pop
24 13b6cb3f Iustin Pop
-}
25 13b6cb3f Iustin Pop
26 13b6cb3f Iustin Pop
module Ganeti.Jobs
27 3f68544e Dato Simó
  ( submitJobs
28 3f68544e Dato Simó
  , execJobsWait
29 7d8b651e Dato Simó
  , execJobsWaitOk
30 369671f4 Dato Simó
  , waitForJobs
31 ebf38064 Iustin Pop
  ) where
32 369671f4 Dato Simó
33 369671f4 Dato Simó
import Control.Concurrent (threadDelay)
34 7d8b651e Dato Simó
import Data.List
35 369671f4 Dato Simó
36 369671f4 Dato Simó
import Ganeti.BasicTypes
37 369671f4 Dato Simó
import Ganeti.Errors
38 369671f4 Dato Simó
import qualified Ganeti.Luxi as L
39 369671f4 Dato Simó
import Ganeti.OpCodes
40 369671f4 Dato Simó
import Ganeti.Types
41 369671f4 Dato Simó
42 3f68544e Dato Simó
-- | Submits a set of jobs and returns their job IDs without waiting for
43 3f68544e Dato Simó
-- completion.
44 3f68544e Dato Simó
submitJobs :: [[MetaOpCode]] -> L.Client -> IO (Result [L.JobId])
45 3f68544e Dato Simó
submitJobs opcodes client = do
46 3f68544e Dato Simó
  jids <- L.submitManyJobs client opcodes
47 3f68544e Dato Simó
  return (case jids of
48 3f68544e Dato Simó
            Bad e    -> Bad $ "Job submission error: " ++ formatError e
49 3f68544e Dato Simó
            Ok jids' -> Ok jids')
50 3f68544e Dato Simó
51 369671f4 Dato Simó
-- | Executes a set of jobs and waits for their completion, returning their
52 369671f4 Dato Simó
-- status.
53 164947cc Dato Simó
execJobsWait :: [[MetaOpCode]]        -- ^ The list of jobs
54 369671f4 Dato Simó
             -> ([L.JobId] -> IO ())  -- ^ Post-submission callback
55 164947cc Dato Simó
             -> L.Client              -- ^ The Luxi client
56 369671f4 Dato Simó
             -> IO (Result [(L.JobId, JobStatus)])
57 164947cc Dato Simó
execJobsWait opcodes callback client = do
58 3f68544e Dato Simó
  jids <- submitJobs opcodes client
59 369671f4 Dato Simó
  case jids of
60 3f68544e Dato Simó
    Bad e -> return $ Bad e
61 369671f4 Dato Simó
    Ok jids' -> do
62 369671f4 Dato Simó
      callback jids'
63 164947cc Dato Simó
      waitForJobs jids' client
64 369671f4 Dato Simó
65 b8e76da8 Dato Simó
-- | Polls a set of jobs at an increasing interval until all are finished one
66 b8e76da8 Dato Simó
-- way or another.
67 164947cc Dato Simó
waitForJobs :: [L.JobId] -> L.Client -> IO (Result [(L.JobId, JobStatus)])
68 b8e76da8 Dato Simó
waitForJobs jids client = waitForJobs' 500000 15000000
69 b8e76da8 Dato Simó
  where
70 b8e76da8 Dato Simó
    waitForJobs' delay maxdelay = do
71 b8e76da8 Dato Simó
      -- TODO: this should use WaitForJobChange once it's available in Haskell
72 b8e76da8 Dato Simó
      -- land, instead of a fixed schedule of sleeping intervals.
73 b8e76da8 Dato Simó
      threadDelay $ min delay maxdelay
74 b8e76da8 Dato Simó
      sts <- L.queryJobsStatus client jids
75 b8e76da8 Dato Simó
      case sts of
76 b8e76da8 Dato Simó
        Bad e -> return . Bad $ "Checking job status: " ++ formatError e
77 b8e76da8 Dato Simó
        Ok sts' -> if any (<= JOB_STATUS_RUNNING) sts' then
78 b8e76da8 Dato Simó
                     waitForJobs' (delay * 2) maxdelay
79 b8e76da8 Dato Simó
                   else
80 b8e76da8 Dato Simó
                     return . Ok $ zip jids sts'
81 7d8b651e Dato Simó
82 7d8b651e Dato Simó
-- | Execute jobs and return @Ok@ only if all of them succeeded.
83 7d8b651e Dato Simó
execJobsWaitOk :: [[MetaOpCode]] -> L.Client -> IO (Result ())
84 7d8b651e Dato Simó
execJobsWaitOk opcodes client = do
85 7d8b651e Dato Simó
  let nullog = const (return () :: IO ())
86 7d8b651e Dato Simó
      failed = filter ((/=) JOB_STATUS_SUCCESS . snd)
87 7d8b651e Dato Simó
      fmtfail (i, s) = show (fromJobId i) ++ "=>" ++ jobStatusToRaw s
88 7d8b651e Dato Simó
  sts <- execJobsWait opcodes nullog client
89 7d8b651e Dato Simó
  case sts of
90 7d8b651e Dato Simó
    Bad e -> return $ Bad e
91 7d8b651e Dato Simó
    Ok sts' -> return (if null $ failed sts' then
92 7d8b651e Dato Simó
                         Ok ()
93 7d8b651e Dato Simó
                       else
94 7d8b651e Dato Simó
                         Bad ("The following jobs failed: " ++
95 7d8b651e Dato Simó
                              (intercalate ", " . map fmtfail $ failed sts')))