Skip to content

Commit

Permalink
[rqd] Adjust shutdown behavior and use Nimby pynput as default. (#1142)
Browse files Browse the repository at this point in the history
  • Loading branch information
DiegoTavares authored May 10, 2022
1 parent 187fe56 commit ae16a2f
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 80 deletions.
16 changes: 7 additions & 9 deletions rqd/deploy/rqd3_init.d
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# RQD3: Start/stop rqd3 services
#
# chkconfig: 345 98 02
# description: RQD for opencue
# description: Opencue RQD agent
#

# Source function library.
Expand All @@ -18,28 +18,26 @@ RQD=${RQD_PATH}rqd.py
start()
{
[ -f /usr/local/etc/sweatbox.csh ] && echo "Refusing to start RQD3 on a sweatbox" && exit 0
echo -n $"Starting rqd3 services:"
echo -n $"Starting openrqd services:"
cd ${RQD_PATH}
daemon "${RQD}" -d
echo ""
}

idle_restart()
{
echo -n "Requesting idle restart of rqd3 services:"
echo -n "Requesting idle restart of openrqd services:"
cd ${RQD_PATH}
daemon "./cuerqd.py" -restart
daemon "rqd/cuerqd.py --restart &>/dev/null || :"
echo ""
}

stop()
{
echo -n "Stopping rqd3 services:"
echo -n "Stopping openrqd services:"
cd ${RQD_PATH}
daemon "./cuerqd.py" -exit_now
sleep 2
killproc ${RQD} >/dev/null 2>&1 || :
echo ""
daemon "rqd/cuerqd.py" --exit_now
echo "Stop Request completed"
}

case "$1" in
Expand Down
8 changes: 7 additions & 1 deletion rqd/rqd/cuerqd.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,13 @@ def shutdownRqdIdle(self):
def shutdownRqdNow(self):
"""Shuts down the host now."""
print(self.rqdHost, "Sending shutdownRqdNow command")
self.stub.ShutdownRqdNow(rqd.compiled_proto.rqd_pb2.RqdStaticShutdownNowRequest())
try:
self.stub.ShutdownRqdNow(rqd.compiled_proto.rqd_pb2.RqdStaticShutdownNowRequest())
# pylint: disable=broad-except
except Exception:
# Shutting down the service from inside means this request will receive
# a connection error response
pass

def restartRqdIdle(self):
"""Restarts RQD on the host when idle."""
Expand Down
2 changes: 1 addition & 1 deletion rqd/rqd/rqconstants.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@
OVERRIDE_PROCS = None # number of physical cpus. ex: None or 2
OVERRIDE_MEMORY = None # in Kb
OVERRIDE_NIMBY = None # True to turn on, False to turn off
USE_NIMBY_PYNPUT = platform.system() == 'Windows'
USE_NIMBY_PYNPUT = True # True pynput, False select
OVERRIDE_HOSTNAME = None # Force to use this hostname
ALLOW_GPU = False
LOAD_MODIFIER = 0 # amount to add/subtract from load
Expand Down
29 changes: 17 additions & 12 deletions rqd/rqd/rqcore.py
Original file line number Diff line number Diff line change
Expand Up @@ -817,15 +817,18 @@ def shutdown(self):
log.warning("Rebooting machine by request")
self.machine.reboot()
else:
log.warning("Shutting down RQD by request")
log.warning("Shutting down RQD by request. pid(%s)", os.getpid())
self.network.stopGrpc()
# Using sys.exit would raise SystemExit, giving exception handlers a chance
# to block this
# pylint: disable=protected-access
os._exit(0)

def handleExit(self, signalnum, flag):
"""Shutdown threads and exit RQD."""
del signalnum
del flag
self.shutdown()
self.network.stopGrpc()
sys.exit()

def launchFrame(self, runFrame):
"""This will setup for the launch the frame specified in the arguments.
Expand Down Expand Up @@ -925,8 +928,12 @@ def reportStatus(self):
def shutdownRqdNow(self):
"""Kill all running frames and shutdown RQD"""
self.machine.state = rqd.compiled_proto.host_pb2.DOWN
self.lockAll()
self.killAllFrame("shutdownRqdNow Command")
try:
self.lockAll()
self.killAllFrame("shutdownRqdNow Command")
# pylint: disable=broad-except
except Exception:
log.exception("Failed to kill frames, stopping service anyways")
if not self.__cache:
self.shutdown()

Expand Down Expand Up @@ -980,14 +987,12 @@ def rebootIdle(self):
def nimbyOn(self):
"""Activates nimby, does not kill any running frames until next nimby
event. Also does not unlock until sufficient idle time is reached."""
if platform.system() != "Windows" and os.getuid() != 0:
log.warning("Not starting nimby, not running as root")
return
if not self.nimby.active:
if self.nimby and not self.nimby.active:
try:
self.nimby.run()
log.info("Nimby has been activated")
except:
log.warning("Nimby has been activated")
# pylint: disable=broad-except
except Exception:
self.nimby.locked = False
err = "Nimby is in the process of shutting down"
log.exception(err)
Expand All @@ -1007,7 +1012,7 @@ def onNimbyLock(self):
self.sendStatusReport()

def onNimbyUnlock(self, asOf=None):
"""This is called by nimby when it unlocks the machine due to sufficent
"""This is called by nimby when it unlocks the machine due to sufficient
idle. A new report is sent to the cuebot.
@param asOf: Time when idle state began, if known."""
del asOf
Expand Down
9 changes: 5 additions & 4 deletions rqd/rqd/rqmachine.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,14 +207,15 @@ def __updateGpuAndLlu(self, frame):
stat = os.stat(frame.runFrame.log_dir_file).st_mtime
frame.lluTime = int(stat)

def _getFields(self, filePath):
def _getFields(self, pidFilePath):
fields = []

try:
with open(filePath, "r") as statFile:
with open(pidFilePath, "r") as statFile:
fields = statFile.read().split()
except rqd.rqexceptions.RqdException as e:
log.warning("Failed to read file: %s", e)
# pylint: disable=broad-except
except Exception:
log.warning("Not able to read pidFilePath: %s", pidFilePath)

return fields

Expand Down
6 changes: 4 additions & 2 deletions rqd/rqd/rqnetwork.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ def kill(self, message=""):
except OSError as e:
log.warning(
"kill() tried to kill a non-existant pid for: %s Error: %s", self.frameId, e)
# pylint: disable=broad-except
except Exception as e:
log.warning("kill() encountered an unknown error: %s", e)
else:
Expand Down Expand Up @@ -226,8 +227,8 @@ def serveForever(self):

def shutdown(self):
"""Stops the gRPC server."""
log.info('Stopping grpc server.')
self.server.stop(0)
log.warning('Stopping grpc server.')
self.server.stop(10)

def stayAlive(self):
"""Runs forever until killed."""
Expand Down Expand Up @@ -255,6 +256,7 @@ def stopGrpc(self):
"""Stops the gRPC server."""
self.grpcServer.shutdown()
del self.grpcServer
log.warning("Stopped grpc server")

def closeChannel(self):
"""Closes the gRPC channel."""
Expand Down
Loading

0 comments on commit ae16a2f

Please sign in to comment.