forked from M-Labs/artiq
1
0
Fork 0

subprocesses: unify termination logic

This commit is contained in:
Robert Jördens 2016-02-01 01:52:31 -07:00
parent cf465dae0c
commit 55006119c8
2 changed files with 55 additions and 38 deletions

View File

@ -106,30 +106,40 @@ class Controller:
await self._terminate() await self._terminate()
async def _terminate(self): async def _terminate(self):
logger.info("Terminating controller %s", self.name) if self.process is None or self.process.returncode is not None:
if self.process is not None and self.process.returncode is None: logger.info("Controller %s already terminated", self.name)
return
logger.debug("Terminating controller %s", self.name)
try: try:
await asyncio.wait_for(self.call("terminate"), await asyncio.wait_for(self.call("terminate"), self.term_timeout)
self.term_timeout) await asyncio.wait_for(self.process.wait(), self.term_timeout)
logger.info("Controller %s terminated", self.name)
return
except: except:
logger.warning("Controller %s did not respond to terminate " logger.warning("Controller %s did not exit on request, "
"command, killing", self.name) "ending the process", self.name)
if os.name != "nt":
try:
self.process.terminate()
except ProcessLookupError:
pass
try:
await asyncio.wait_for(self.process.wait(), self.term_timeout)
logger.info("Controller process %s terminated", self.name)
return
except asyncio.TimeoutError:
logger.warning("Controller process %s did not terminate, "
"killing", self.name)
try: try:
self.process.kill() self.process.kill()
except ProcessLookupError: except ProcessLookupError:
pass pass
try: try:
await asyncio.wait_for(self.process.wait(), await asyncio.wait_for(self.process.wait(), self.term_timeout)
self.term_timeout) logger.info("Controller process %s killed", self.name)
except: return
logger.warning("Controller %s failed to exit, killing", except asyncio.TimeoutError:
self.name) logger.warning("Controller process %s failed to die", self.name)
try:
self.process.kill()
except ProcessLookupError:
pass
await self.process.wait()
logger.debug("Controller %s terminated", self.name)
def get_ip_addresses(host): def get_ip_addresses(host):

View File

@ -115,30 +115,37 @@ class Worker:
" (RID %s)", self.ipc.process.returncode, " (RID %s)", self.ipc.process.returncode,
self.rid) self.rid)
return return
obj = {"action": "terminate"}
try: try:
await self._send(obj, cancellable=False) await self._send({"action": "terminate"}, cancellable=False)
await asyncio.wait_for(self.ipc.process.wait(), term_timeout)
logger.debug("worker exited on request (RID %s)", self.rid)
return
except: except:
logger.debug("failed to send terminate command to worker" logger.debug("worker failed to exit on request"
" (RID %s), killing", self.rid, exc_info=True) " (RID %s), ending the process", self.rid,
exc_info=True)
if os.name != "nt":
try: try:
self.ipc.process.kill() self.ipc.process.terminate()
except ProcessLookupError: except ProcessLookupError:
pass pass
await self.ipc.process.wait()
return
try: try:
await asyncio.wait_for(self.ipc.process.wait(), term_timeout) await asyncio.wait_for(self.ipc.process.wait(), term_timeout)
logger.debug("worker terminated (RID %s)", self.rid)
return
except asyncio.TimeoutError: except asyncio.TimeoutError:
logger.debug("worker did not exit by itself (RID %s), killing", logger.warning("worker did not terminate (RID %s), killing",
self.rid) self.rid)
try: try:
self.ipc.process.kill() self.ipc.process.kill()
except ProcessLookupError: except ProcessLookupError:
pass pass
await self.ipc.process.wait() try:
else: await asyncio.wait_for(self.ipc.process.wait(), term_timeout)
logger.debug("worker exited by itself (RID %s)", self.rid) logger.debug("worker killed (RID %s)", self.rid)
return
except asyncio.TimeoutError:
logger.warning("worker refuses to die (RID %s)", self.rid)
finally: finally:
self.io_lock.release() self.io_lock.release()