diff --git a/lib/constants.py b/lib/constants.py index fff1a662ead6e9267253e7baa7e5e93e7503e983..4e04dff4fc06472cf34232bbe1849a4ceaf70fc4 100644 --- a/lib/constants.py +++ b/lib/constants.py @@ -1,7 +1,7 @@ # # -# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Google Inc. +# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Google Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -2194,14 +2194,16 @@ CONFD_ERROR_ARGUMENT = 3 # TODO: make this a default and allow the value to be more configurable CONFD_MAX_CLOCK_SKEW = 2 * NODE_MAX_CLOCK_SKEW -# When we haven't reloaded the config for more than this amount of seconds, we -# force a test to see if inotify is betraying us. -CONFD_CONFIG_RELOAD_TIMEOUT = 60 +# When we haven't reloaded the config for more than this amount of +# seconds, we force a test to see if inotify is betraying us. Using a +# prime number to ensure we get less chance of 'same wakeup' with +# other processes. +CONFD_CONFIG_RELOAD_TIMEOUT = 17 -# If we receive more than one update in this amount of seconds, we move to -# polling every RATELIMIT seconds, rather than relying on inotify, to be able -# to serve more requests. -CONFD_CONFIG_RELOAD_RATELIMIT = 2 +# If we receive more than one update in this amount of microseconds, +# we move to polling every RATELIMIT seconds, rather than relying on +# inotify, to be able to serve more requests. +CONFD_CONFIG_RELOAD_RATELIMIT = 250000 # Magic number prepended to all confd queries. # This allows us to distinguish different types of confd protocols and handle diff --git a/src/Ganeti/Confd/Server.hs b/src/Ganeti/Confd/Server.hs index cf0cebb01fac4f62a9b017b1e955f730cec3c1fc..d5e1b02f531c598ea8c5890335df571e1f11b5b7 100644 --- a/src/Ganeti/Confd/Server.hs +++ b/src/Ganeti/Confd/Server.hs @@ -84,7 +84,7 @@ data ReloadModel = ReloadNotify -- ^ We are using notifications -- | Server state data type. data ServerState = ServerState { reloadModel :: ReloadModel - , reloadTime :: Integer + , reloadTime :: Integer -- ^ Reload time (epoch) in microseconds , reloadFStat :: FStat } @@ -98,11 +98,11 @@ configReloadTimeout = C.confdConfigReloadTimeout * 1000000 -- | Ratelimit timeout in microseconds. configReloadRatelimit :: Int -configReloadRatelimit = C.confdConfigReloadRatelimit * 1000000 +configReloadRatelimit = C.confdConfigReloadRatelimit --- | Ratelimit timeout in seconds, as an 'Integer'. -reloadRatelimitSec :: Integer -reloadRatelimitSec = fromIntegral C.confdConfigReloadRatelimit +-- | Ratelimit timeout in microseconds, as an 'Integer'. +reloadRatelimit :: Integer +reloadRatelimit = fromIntegral C.confdConfigReloadRatelimit -- | Initial poll round. initialPoll :: ReloadModel @@ -351,6 +351,7 @@ needsReload oldstat path = do onTimeoutTimer :: IO Bool -> FilePath -> CRef -> MVar ServerState -> IO () onTimeoutTimer inotiaction path cref state = do threadDelay configReloadTimeout + logDebug "Watcher timer fired" modifyMVar_ state (onTimeoutInner path cref) _ <- inotiaction onTimeoutTimer inotiaction path cref state @@ -372,6 +373,7 @@ onTimeoutInner path cref state = do -- notification. onReloadTimer :: IO Bool -> FilePath -> CRef -> MVar ServerState -> IO () onReloadTimer inotiaction path cref state = do + logDebug "Reload timer fired" continue <- modifyMVar state (onReloadInner inotiaction path cref) when continue $ do threadDelay configReloadRatelimit @@ -440,10 +442,10 @@ onInotify inotify path cref mstate _ = modifyMVar_ mstate $ \state -> if reloadModel state == ReloadNotify then do - ctime <- getCurrentTime + ctime <- getCurrentTimeUSec (newfstat, _) <- safeUpdateConfig path (reloadFStat state) cref let state' = state { reloadFStat = newfstat, reloadTime = ctime } - if abs (reloadTime state - ctime) < reloadRatelimitSec + if abs (reloadTime state - ctime) < reloadRatelimit then do mode <- moveToPolling "too many reloads" inotify path cref mstate return state' { reloadModel = mode }