|
|
|
@ -87,7 +87,40 @@ class WorkerProcess(multiprocessing.Process):
|
|
|
|
|
# set to /dev/null
|
|
|
|
|
self._new_stdin = os.devnull
|
|
|
|
|
|
|
|
|
|
def _hard_exit(self, e):
|
|
|
|
|
'''
|
|
|
|
|
There is no safe exception to return to higher level code that does not
|
|
|
|
|
risk an innocent try/except finding itself executing in the wrong
|
|
|
|
|
process. All code executing above WorkerProcess.run() on the stack
|
|
|
|
|
conceptually belongs to another program.
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
display.debug(u"WORKER HARD EXIT: %s" % to_text(e))
|
|
|
|
|
except BaseException:
|
|
|
|
|
# If the cause of the fault is IOError being generated by stdio,
|
|
|
|
|
# attempting to log a debug message may trigger another IOError.
|
|
|
|
|
# Try printing once then give up.
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
os._exit(1)
|
|
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
|
'''
|
|
|
|
|
Wrap _run() to ensure no possibility an errant exception can cause
|
|
|
|
|
control to return to the StrategyBase task loop, or any other code
|
|
|
|
|
higher in the stack.
|
|
|
|
|
|
|
|
|
|
As multiprocessing in Python 2.x provides no protection, it is possible
|
|
|
|
|
a try/except added in far-away code can cause a crashed child process
|
|
|
|
|
to suddenly assume the role and prior state of its parent.
|
|
|
|
|
'''
|
|
|
|
|
try:
|
|
|
|
|
return self._run()
|
|
|
|
|
except BaseException as e:
|
|
|
|
|
self._hard_exit(e)
|
|
|
|
|
|
|
|
|
|
def _run(self):
|
|
|
|
|
'''
|
|
|
|
|
Called when the process is started. Pushes the result onto the
|
|
|
|
|
results queue. We also remove the host from the blocked hosts list, to
|
|
|
|
|