Revision 1e0d1a19

b/src/Ganeti/WConfd/ConfigWriter.hs
40 40
import Control.Monad.Base
41 41
import Control.Monad.Error
42 42
import qualified Control.Monad.State.Strict as S
43
import Control.Monad.Trans.Control
43 44

  
44 45
import Ganeti.BasicTypes
45 46
import Ganeti.Errors
......
80 81
      setOwnerWGroupR fname
81 82
      saveConfig fh cfg
82 83

  
84
-- Reads the current configuration state in the 'WConfdMonad'.
85
readConfig :: WConfdMonad ConfigData
86
readConfig = csConfigData <$> readConfigState
87

  
88
-- Replaces the current configuration state within the 'WConfdMonad'.
89
writeConfig :: ConfigData -> WConfdMonad ()
90
writeConfig cd = modifyConfigState $ const (mkConfigState cd, ())
91

  
92
-- * Asynchronous tasks
93

  
94
-- | Creates an asynchronous task that handles errors in its actions.
95
-- If an error occurs, it's logged and the internal state remains unchanged.
96
mkStatefulAsyncTask :: (MonadBaseControl IO m, Show e)
97
                    => Priority
98
                    -> String
99
                    -> (s -> ResultT e m s)
100
                    -> s
101
                    -> m (AsyncWorker ())
102
mkStatefulAsyncTask logPrio logPrefix action start =
103
    flip S.evalStateT start . mkAsyncWorker $
104
      S.get >>= lift . runResultT . action
105
            >>= genericResult
106
                  (logAt logPrio . (++) (logPrefix ++ ": ") . show)
107
                  S.put -- on success save the state
108

  
83 109
-- | Construct an asynchronous worker whose action is to save the
84 110
-- configuration to the master file.
85 111
-- The worker's action reads the configuration using the given @IO@ action
......
90 116
                    -> IO ConfigState -- ^ An action to read the current config
91 117
                    -> ResultG (AsyncWorker ())
92 118
saveConfigAsyncTask fpath fstat cdRef =
93
  flip S.evalStateT fstat . mkAsyncWorker $
94
    catchError (do
95
        oldstat <- S.get
96
        cd <- liftBase (csConfigData `liftM` cdRef)
97
        newstat <- writeConfigToFile cd fpath oldstat
98
        S.put newstat
99
      ) (logEmergency . (++) "Can't write the master configuration file: "
100
                      . show)
101

  
102
-- Reads the current configuration state in the 'WConfdMonad'.
103
readConfig :: WConfdMonad ConfigData
104
readConfig = csConfigData <$> readConfigState
105

  
106
-- Replaces the current configuration state within the 'WConfdMonad'.
107
writeConfig :: ConfigData -> WConfdMonad ()
108
writeConfig cd = modifyConfigState $ const (mkConfigState cd, ())
119
  let action oldstat = do
120
                        cd <- liftBase (csConfigData `liftM` cdRef)
121
                        writeConfigToFile cd fpath oldstat
122
  in lift $ mkStatefulAsyncTask
123
              EMERGENCY "Can't write the master configuration file"
124
              action fstat

Also available in: Unified diff