Revision b57c50de

b/src/Ganeti/WConfd/DeathDetection.hs
32 32

  
33 33
module Ganeti.WConfd.DeathDetection
34 34
  ( isDead
35
  , cleanupLocksTask
35 36
  ) where
36 37

  
38
import Control.Concurrent (threadDelay)
37 39
import Control.Exception (bracket)
38 40
import Control.Monad
39 41
import System.Directory
......
41 43
import System.Posix.IO
42 44

  
43 45
import Ganeti.BasicTypes
46
import qualified Ganeti.Constants as C
47
import qualified Ganeti.Locking.Allocation as L
48
import Ganeti.Logging.Lifted (logDebug, logInfo)
49
import Ganeti.WConfd.Monad
44 50

  
45 51
-- | Detect whether a the process identified by the given path
46 52
-- does not exist any more. This function never fails and only
......
53 59
  when filepresent
54 60
    $ bracket (openFd fpath ReadOnly Nothing defaultFileFlags) closeFd
55 61
              (`setLock` (ReadLock, AbsoluteSeek, 0, 0))
62

  
63
-- | Interval to run clean-up tasks in microseconds
64
cleanupInterval :: Int
65
cleanupInterval = C.wconfdDeathdetectionIntervall * 1000000
66

  
67
-- | Thread periodically cleaning up locks of lock owners that died.
68
cleanupLocksTask :: WConfdMonadInt ()
69
cleanupLocksTask = forever . runResultT $ do
70
  logDebug "Death detection timer fired"
71
  owners <- liftM L.lockOwners readLockAllocation
72
  logDebug $ "Current lock owners: " ++ show owners
73
  let cleanupIfDead owner@(_, fpath) = do
74
        died <- liftIO (isDead fpath)
75
        when died $ do
76
          logInfo $ show owner ++ " died, releasing locks"
77
          modifyLockAllocation_ (`L.freeLocks` owner)
78
  mapM_ cleanupIfDead owners
79
  liftIO $ threadDelay cleanupInterval

Also available in: Unified diff