> While the client will timeout on its own, it'd be probably better to
> close it explicitly using `bracket` or so when not needed any more.
As this is a recurring topic, I suggest the interdiff
diff --git a/src/Ganeti/MaintD/Server.hs b/src/Ganeti/MaintD/Server.hs
index ef0134c..4ab74b9 100644
--- a/src/Ganeti/MaintD/Server.hs
+++ b/src/Ganeti/MaintD/Server.hs
@@ -61,7 +61,6 @@ import Ganeti.Daemon.Utils
(handleMasterVerificationOptions)
import qualified Ganeti.HTools.Backend.Luxi as Luxi
import qualified Ganeti.HTools.Container as Container
import Ganeti.HTools.Loader (ClusterData(..), mergeData, checkData)
-import Ganeti.THH.HsRPC (runRpcClient)
import Ganeti.Logging.Lifted
import Ganeti.MaintD.Autorepairs (harepTasks)
import qualified Ganeti.Path as Path
@@ -69,7 +68,7 @@ import Ganeti.Runtime (GanetiDaemon(GanetiMaintd))
import Ganeti.Types (JobId(..))
import Ganeti.Utils (threadDelaySeconds)
import Ganeti.Utils.Http (httpConfFromOpts, plainJSON, error404)
-import Ganeti.WConfd.Client (getWConfdClient, maintenanceRoundDelay)
+import Ganeti.WConfd.Client (runNewWConfdClient, maintenanceRoundDelay)
-- | Options list and functions.
options :: [OptType]
@@ -112,8 +111,7 @@ loadClusterData = do
-- | Perform one round of maintenance
maintenance :: ResultT String IO ()
maintenance = do
- wconfdClient <- liftIO $ getWConfdClient =<< Path.defaultWConfdSocket
- delay <- withErrorT show $ runRpcClient maintenanceRoundDelay
wconfdClient
+ delay <- withErrorT show $ runNewWConfdClient maintenanceRoundDelay
liftIO $ threadDelaySeconds delay
logDebug "New round of maintenance started"
cData <- loadClusterData
after adding the following patch at the very beginning of the patch series.
commit ff969d52acff032b4281c531b08002c0286aa3ee
Author: Klaus Aehlig <[email protected]>
Date: Thu Jul 16 11:55:12 2015 +0200
Add a utility to run an Rpc call in a new WConfD client
...that takes care of creating and closing the client
properly.
diff --git a/src/Ganeti/WConfd/Client.hs b/src/Ganeti/WConfd/Client.hs
index a477907..f6981a9 100644
--- a/src/Ganeti/WConfd/Client.hs
+++ b/src/Ganeti/WConfd/Client.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TemplateHaskell, FlexibleContexts #-}
{-| The Ganeti WConfd client functions.
@@ -39,13 +39,21 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
module Ganeti.WConfd.Client where
import Control.Exception.Lifted (bracket)
+import Control.Monad (unless)
+import Control.Monad.Base
+import Control.Monad.Error (MonadError)
+import Control.Monad.IO.Class (liftIO)
+import Control.Monad.Trans.Control (MonadBaseControl)
import Ganeti.THH.HsRPC
import Ganeti.Constants
+import Ganeti.Errors (GanetiException)
import Ganeti.JSON (unMaybeForJSON)
import Ganeti.Locking.Locks (ClientId)
import Ganeti.Objects (ConfigData)
-import Ganeti.UDSServer (ConnectConfig(..), Client, connectClient)
+import qualified Ganeti.Path as Path
+import Ganeti.THH.HsRPC
+import Ganeti.UDSServer (ConnectConfig(..), Client, connectClient, closeClient)
import Ganeti.WConfd.Core (exportedFunctions)
-- * Generated client functions
@@ -65,6 +73,15 @@ wconfdConnectConfig = ConnectConfig { recvTmo =
wconfdDefRwto
getWConfdClient :: FilePath -> IO Client
getWConfdClient = connectClient wconfdConnectConfig wconfdDefCtmo
+-- | Run an Rpc with a fresh client.
+runNewWConfdClient :: ( MonadBase IO m, MonadBaseControl IO m
+ , MonadError GanetiException m )
+ => RpcClientMonad a -> m a
+runNewWConfdClient request =
+ bracket (liftBase (Path.defaultWConfdSocket >>= getWConfdClient))
+ (liftBase . closeClient)
+ $ runRpcClient request
+
-- * Helper functions for getting a remote lock
-- | Calls the `lockConfig` RPC until the lock is obtained.
--
Klaus Aehlig
Google Germany GmbH, Dienerstr. 12, 80331 Muenchen
Registergericht und -nummer: Hamburg, HRB 86891
Sitz der Gesellschaft: Hamburg
Geschaeftsfuehrer: Graham Law, Christine Elizabeth Flores