2011-10-07 17:43:45 +02:00
import threading
from PowerState import *
from ClusterNodeStatusUpdater import *
import Lib . Util
import Lib . SimpaDbUtil
from datetime import *
class ClusterNode :
"""
the state of a machine node
"""
def __init__ ( self , machineName , cluster , gridEngine ) :
self . m_name = machineName
self . m_cluster = cluster # the cluster this machine belongs to
self . m_requestedPowerState = PowerState . ON
self . m_powerState = PowerState . UNKNOWN
self . m_lastPowerStateTime = None # time at which the last value of self.m_powerState has been set
self . m_machineStatusUpdater = ClusterNodeStatusUpdater ( machineName , self , gridEngine )
self . m_energyConsumption = 0.0 # estimate of the energy consumption of this machine since the start of cluster controller (in joules)
self . m_energySavings = 0.0 # estimate of the energy savings on this machine caused by the cluster controller since it started (in joules)
def getName ( self ) :
return self . m_name
def isReady ( self ) :
if self . m_powerState == PowerState . UNKNOWN :
#logInfo( self.m_name + ' is not ready (waiting for power state)' )
return False
if self . m_powerState == PowerState . ON :
return True
#log( self.m_name + ' is ready' )
return True
def getPowerState ( self ) :
return self . m_powerState
def setShouldAlwaysBeOn ( self ) :
self . m_machineStatusUpdater . setShouldAlwaysBeOn ( )
self . setPowerState ( PowerState . ON )
def setPowerState ( self , powerState ) :
bUpdateRequiredChecks = False
if self . m_powerState == PowerState . UNKNOWN :
logInfo ( ' ClusterNode::setPowerState : ' + self . m_name + ' \' s power state has been initialized to ' + PowerStateToStr ( powerState ) )
self . m_powerState = powerState
self . m_lastPowerStateTime = datetime . now ( )
bUpdateRequiredChecks = True
else :
# update the estimation of energy consumption
self . updateEnergyMeasurements ( )
# then change the power state
if self . m_powerState != powerState :
logInfo ( ' ClusterNode::setPowerState : ' + self . m_name + ' \' s power state has been changed to ' + PowerStateToStr ( powerState ) )
self . m_powerState = powerState
self . m_lastPowerStateTime = datetime . now ( )
bUpdateRequiredChecks = True
if bUpdateRequiredChecks :
if self . m_powerState == PowerState . ON :
2012-06-28 14:22:07 +02:00
self . m_machineStatusUpdater . m_bCheckPowerState = True
self . m_machineStatusUpdater . m_bCheckSensors = True
2011-10-07 17:43:45 +02:00
elif self . m_powerState == PowerState . OFF :
2012-06-28 14:22:07 +02:00
self . m_machineStatusUpdater . m_bCheckPowerState = True
self . m_machineStatusUpdater . m_bCheckSensors = False
2011-10-07 17:43:45 +02:00
elif self . m_powerState == PowerState . SLEEP :
2012-06-28 14:22:07 +02:00
self . m_machineStatusUpdater . m_bCheckPowerState = True
self . m_machineStatusUpdater . m_bCheckSensors = False
2011-10-07 17:43:45 +02:00
elif self . m_powerState == PowerState . UNPLUGGED :
2012-06-28 14:22:07 +02:00
self . m_machineStatusUpdater . m_bCheckPowerState = True
self . m_machineStatusUpdater . m_bCheckSensors = False
2011-10-07 17:43:45 +02:00
else :
assert ( False )
def onNewPowerStateReading ( self , powerState ) :
"""
called when a new powerstate reading arrives
"""
if powerState != self . getPowerState ( ) :
if self . getPowerState ( ) != PowerState . UNKNOWN :
logWarning ( ' ClusterNode::onNewPowerStateReading : ' + self . m_name + ' \' s power state has been (manually it seems) changed to ' + PowerStateToStr ( powerState ) )
self . setPowerState ( powerState )
def getPowerConsumptionForPowerState ( self , ePowerState ) :
"""
returns the power consumption estimation ( in watts ) of this machine for the given power state
"""
fCurrentIntensity = 0.0
fCurrentVoltage = 220.0
# noticed on 26.08.2009 that putting 22 machines from sleep to on eats 17 A, resulting in difference of 0.77 A per machine
if ePowerState == PowerState . ON :
fCurrentIntensity = 0.9 # value when the machine is doing nothing
elif ePowerState == PowerState . OFF :
fCurrentIntensity = 0.1
elif ePowerState == PowerState . SLEEP :
fCurrentIntensity = 0.1
elif ePowerState == PowerState . UNPLUGGED :
fCurrentIntensity = 0.0
else :
assert ( False )
return fCurrentIntensity * fCurrentVoltage
def updateEnergyMeasurements ( self ) :
timeInterval = datetime . now ( ) - self . m_lastPowerStateTime
self . m_energyConsumption + = self . getPowerConsumptionForPowerState ( self . m_powerState ) * timeInterval . seconds
self . m_energySavings + = ( self . getPowerConsumptionForPowerState ( PowerState . ON ) - self . getPowerConsumptionForPowerState ( self . m_powerState ) ) * timeInterval . seconds
self . m_lastPowerStateTime = datetime . now ( )
#logDebug('energy savings on %s : %f J' %(self.getName(), self.m_energySavings))
def getEnergyConsumption ( self ) :
"""
in joules
"""
self . updateEnergyMeasurements ( )
return self . m_energyConsumption
def getPowerConsumption ( self ) :
fCurrentPowerConsumption = self . getPowerConsumptionForPowerState ( self . m_powerState )
#logDebug('getPowerConsumption of %s : %f (powerstate = %d)' % (self.getName(), fCurrentPowerConsumption, self.m_powerState))
return fCurrentPowerConsumption
def getEnergySavings ( self ) :
self . updateEnergyMeasurements ( )
return self . m_energySavings
def onSleepFailedBecauseAJobJustArrived ( self ) :
logInfo ( ' %s was scheduled to sleep but the sleep is canceled because it \' s currently executing a new job ' % self . m_name )
def requestSleep ( self , sleepCompleteNotifier = None ) :
self . m_machineStatusUpdater . requestSleep ( sleepCompleteNotifier )
def requestWakeUp ( self , wakeUpCompleteNotifier = None ) :
self . m_machineStatusUpdater . requestWakeUp ( wakeUpCompleteNotifier )
def getQueueMachineName ( self ) :
return self . getCluster ( ) . getJobsState ( ) . getQueueMachine ( self . m_name ) . getName ( )
assert ( self . m_queueName != None )
return self . m_queueName
def getCluster ( self ) :
return self . m_cluster