mirror of
https://github.com/internetarchive/brozzler.git
synced 2025-02-24 08:39:59 -05:00
make state dumping signal handler more robust (now you can kill -QUIT a thousand times in a row without causing problems)
This commit is contained in:
parent
c6e6b34e82
commit
04e1e5277e
@ -210,7 +210,6 @@ def brozzler_worker():
|
|||||||
Main entrypoint for brozzler, gets sites and pages to brozzle from
|
Main entrypoint for brozzler, gets sites and pages to brozzle from
|
||||||
rethinkdb, brozzles them.
|
rethinkdb, brozzles them.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
arg_parser = argparse.ArgumentParser(
|
arg_parser = argparse.ArgumentParser(
|
||||||
prog=os.path.basename(__file__),
|
prog=os.path.basename(__file__),
|
||||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
||||||
@ -231,21 +230,35 @@ def brozzler_worker():
|
|||||||
def sigint(signum, frame):
|
def sigint(signum, frame):
|
||||||
raise brozzler.ShutdownRequested('shutdown requested (caught SIGINT)')
|
raise brozzler.ShutdownRequested('shutdown requested (caught SIGINT)')
|
||||||
|
|
||||||
def dump_state(signum, frame):
|
# do not print in signal handler to avoid RuntimeError: reentrant call
|
||||||
state_strs = []
|
state_dump_msgs = []
|
||||||
for th in threading.enumerate():
|
def queue_state_dump(signum, frame):
|
||||||
state_strs.append(str(th))
|
signal.signal(signal.SIGQUIT, signal.SIG_IGN)
|
||||||
stack = traceback.format_stack(sys._current_frames()[th.ident])
|
try:
|
||||||
state_strs.append("".join(stack))
|
state_strs = []
|
||||||
logging.warn("dumping state (caught signal {})\n{}".format(
|
frames = sys._current_frames()
|
||||||
signum, "\n".join(state_strs)))
|
threads = {th.ident: th for th in threading.enumerate()}
|
||||||
|
for ident in frames:
|
||||||
|
if threads[ident]:
|
||||||
|
state_strs.append(str(threads[ident]))
|
||||||
|
else:
|
||||||
|
state_strs.append('<???:thread:ident=%s>' % ident)
|
||||||
|
stack = traceback.format_stack(frames[ident])
|
||||||
|
state_strs.append(''.join(stack))
|
||||||
|
state_dump_msgs.append(
|
||||||
|
'dumping state (caught signal %s)\n%s' % (
|
||||||
|
signum, '\n'.join(state_strs)))
|
||||||
|
except BaseException as e:
|
||||||
|
state_dump_msgs.append('exception dumping state: %s' % e)
|
||||||
|
finally:
|
||||||
|
signal.signal(signal.SIGQUIT, queue_state_dump)
|
||||||
|
|
||||||
signal.signal(signal.SIGQUIT, dump_state)
|
signal.signal(signal.SIGQUIT, queue_state_dump)
|
||||||
signal.signal(signal.SIGTERM, sigterm)
|
signal.signal(signal.SIGTERM, sigterm)
|
||||||
signal.signal(signal.SIGINT, sigint)
|
signal.signal(signal.SIGINT, sigint)
|
||||||
|
|
||||||
r = rethinkstuff.Rethinker(
|
r = rethinkstuff.Rethinker(
|
||||||
args.rethinkdb_servers.split(","), args.rethinkdb_db)
|
args.rethinkdb_servers.split(','), args.rethinkdb_db)
|
||||||
frontier = brozzler.RethinkDbFrontier(r)
|
frontier = brozzler.RethinkDbFrontier(r)
|
||||||
service_registry = rethinkstuff.ServiceRegistry(r)
|
service_registry = rethinkstuff.ServiceRegistry(r)
|
||||||
worker = brozzler.worker.BrozzlerWorker(
|
worker = brozzler.worker.BrozzlerWorker(
|
||||||
@ -255,14 +268,16 @@ def brozzler_worker():
|
|||||||
worker.start()
|
worker.start()
|
||||||
try:
|
try:
|
||||||
while worker.is_alive():
|
while worker.is_alive():
|
||||||
|
while state_dump_msgs:
|
||||||
|
logging.warn(state_dump_msgs.pop(0))
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
logging.critical("worker thread has died, shutting down")
|
logging.critical('worker thread has died, shutting down')
|
||||||
except brozzler.ShutdownRequested as e:
|
except brozzler.ShutdownRequested as e:
|
||||||
pass
|
pass
|
||||||
finally:
|
finally:
|
||||||
worker.shutdown_now()
|
worker.shutdown_now()
|
||||||
|
|
||||||
logging.info("brozzler-worker is all done, exiting")
|
logging.info('brozzler-worker is all done, exiting')
|
||||||
|
|
||||||
def brozzler_ensure_tables():
|
def brozzler_ensure_tables():
|
||||||
'''
|
'''
|
||||||
|
2
setup.py
2
setup.py
@ -21,7 +21,7 @@ import setuptools
|
|||||||
|
|
||||||
setuptools.setup(
|
setuptools.setup(
|
||||||
name='brozzler',
|
name='brozzler',
|
||||||
version='1.1b3.dev50',
|
version='1.1b3.dev51',
|
||||||
description='Distributed web crawling with browsers',
|
description='Distributed web crawling with browsers',
|
||||||
url='https://github.com/internetarchive/brozzler',
|
url='https://github.com/internetarchive/brozzler',
|
||||||
author='Noah Levitt',
|
author='Noah Levitt',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user