forked from M-Labs/artiq
subprocesses: unify termination logic
This commit is contained in:
parent
cf465dae0c
commit
55006119c8
|
@ -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):
|
||||||
|
|
|
@ -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()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue