1 |
|
{-# LANGUAGE MultiParamTypeClasses, TypeFamilies #-}
|
|
1 |
{-# LANGUAGE MultiParamTypeClasses, TypeFamilies, FlexibleContexts #-}
|
2 |
2 |
|
3 |
3 |
{-| All RPC calls are run within this monad.
|
4 |
4 |
|
... | ... | |
37 |
37 |
module Ganeti.WConfd.Monad
|
38 |
38 |
( DaemonHandle
|
39 |
39 |
, dhConfigPath
|
|
40 |
, dhSaveConfigWorker
|
40 |
41 |
, mkDaemonHandle
|
41 |
42 |
, ClientState(..)
|
42 |
43 |
, WConfdMonadInt
|
43 |
44 |
, runWConfdMonadInt
|
44 |
45 |
, WConfdMonad
|
|
46 |
, daemonHandle
|
45 |
47 |
, modifyConfigState
|
|
48 |
, readConfigState
|
46 |
49 |
, modifyLockAllocation
|
47 |
50 |
) where
|
48 |
51 |
|
... | ... | |
52 |
55 |
import Control.Monad.Error
|
53 |
56 |
import Control.Monad.Trans.Control
|
54 |
57 |
import Control.Monad.Trans.RWS.Strict
|
55 |
|
import Data.IORef
|
|
58 |
import Data.IORef.Lifted
|
56 |
59 |
|
57 |
60 |
import Ganeti.BasicTypes
|
58 |
61 |
import Ganeti.Errors
|
59 |
62 |
import Ganeti.Locking.Locks
|
60 |
63 |
import Ganeti.Logging
|
61 |
64 |
import Ganeti.Types
|
|
65 |
import Ganeti.Utils.AsyncWorker
|
62 |
66 |
import Ganeti.WConfd.ConfigState
|
63 |
67 |
|
64 |
68 |
-- * Pure data types used in the monad
|
... | ... | |
76 |
80 |
-- all static information that doesn't change during the life-time of the
|
77 |
81 |
-- daemon should go here;
|
78 |
82 |
-- all IDs of threads that do asynchronous work should probably also go here
|
|
83 |
, dhSaveConfigWorker :: AsyncWorker ()
|
79 |
84 |
}
|
80 |
85 |
|
81 |
86 |
mkDaemonHandle :: FilePath
|
82 |
87 |
-> ConfigState
|
83 |
88 |
-> GanetiLockAllocation
|
84 |
|
-> ResultT GanetiException IO DaemonHandle
|
85 |
|
mkDaemonHandle cp cs la =
|
86 |
|
DaemonHandle <$> liftBase (newIORef $ DaemonState cs la) <*> pure cp
|
|
89 |
-> (IO ConfigState -> ResultG (AsyncWorker ()))
|
|
90 |
-- ^ A function that creates a worker that asynchronously
|
|
91 |
-- saves the configuration to the master file.
|
|
92 |
-> ResultG DaemonHandle
|
|
93 |
mkDaemonHandle cpath cstat lstat saveWorkerFn = do
|
|
94 |
ds <- newIORef $ DaemonState cstat lstat
|
|
95 |
saveWorker <- saveWorkerFn $ dsConfigState `liftM` readIORef ds
|
|
96 |
return $ DaemonHandle ds cpath saveWorker
|
87 |
97 |
|
88 |
98 |
data ClientState = ClientState
|
89 |
99 |
{ clLiveFilePath :: FilePath
|
... | ... | |
138 |
148 |
|
139 |
149 |
-- * Basic functions in the monad
|
140 |
150 |
|
|
151 |
-- | Returns the daemon handle.
|
|
152 |
daemonHandle :: WConfdMonad DaemonHandle
|
|
153 |
daemonHandle = lift . WConfdMonadInt $ ask
|
|
154 |
|
|
155 |
-- | Returns the current configuration, given a handle
|
|
156 |
readConfigState :: WConfdMonad ConfigState
|
|
157 |
readConfigState = liftM dsConfigState . readIORef . dhDaemonState
|
|
158 |
=<< daemonHandle
|
|
159 |
|
141 |
160 |
-- | Atomically modifies the configuration state in the WConfdMonad.
|
142 |
161 |
modifyConfigState :: (ConfigState -> (ConfigState, a)) -> WConfdMonad a
|
143 |
162 |
modifyConfigState f = do
|
144 |
|
dh <- lift . WConfdMonadInt $ ask
|
|
163 |
dh <- daemonHandle
|
145 |
164 |
-- TODO: Use lenses to modify the daemons state here
|
146 |
165 |
let mf ds = let (cs', r) = f (dsConfigState ds)
|
147 |
166 |
in (ds { dsConfigState = cs' }, r)
|
148 |
|
liftBase $ atomicModifyIORef (dhDaemonState dh) mf
|
|
167 |
r <- atomicModifyIORef (dhDaemonState dh) mf
|
|
168 |
-- trigger the config. saving worker and wait for it
|
|
169 |
logDebug "Triggering config write"
|
|
170 |
liftBase . triggerAndWait . dhSaveConfigWorker $ dh
|
|
171 |
logDebug "Config write finished"
|
|
172 |
-- trigger the config. distribution worker asynchronously
|
|
173 |
-- TODO
|
|
174 |
return r
|
149 |
175 |
|
150 |
176 |
-- | Atomically modifies the lock allocation state in WConfdMonad.
|
151 |
177 |
modifyLockAllocation :: (GanetiLockAllocation -> (GanetiLockAllocation, a))
|
... | ... | |
154 |
180 |
dh <- lift . WConfdMonadInt $ ask
|
155 |
181 |
let mf ds = let (la', r) = f (dsLockAllocation ds)
|
156 |
182 |
in (ds { dsLockAllocation = la' }, r)
|
157 |
|
liftBase $ atomicModifyIORef (dhDaemonState dh) mf
|
|
183 |
atomicModifyIORef (dhDaemonState dh) mf
|
|
184 |
-- TODO: Trigger the async. lock saving worker
|