Skip to content

Commit

Permalink
Use sigchld instead of polling children
Browse files Browse the repository at this point in the history
  • Loading branch information
sileht committed Jan 16, 2017
1 parent ea3b6ae commit 64fea67
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 6 deletions.
6 changes: 5 additions & 1 deletion cotyledon/_service_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ def __init__(self, wait_interval=0.01, graceful_shutdown_timeout=60):
self._death_detection_pipe = multiprocessing.Pipe(duplex=False)

signal.signal(signal.SIGINT, self._fast_exit)
signal.signal(signal.SIGCHLD, self._signal_catcher)

def register_hooks(self, on_terminate=None, on_reload=None,
on_new_worker=None):
Expand Down Expand Up @@ -203,9 +204,10 @@ def run(self):
"""

self._systemd_notify_once()
self._spawn_missing_workers()
self._wait_forever()

def _on_wakeup(self):
def _spawn_missing_workers(self):
info = self._get_last_worker_died()
while info is not None:
service_id, worker_id = info
Expand All @@ -220,6 +222,8 @@ def _on_signal_received(self, sig):
self._shutdown()
elif sig == _utils.SIGHUP:
self._reload()
elif sig == signal.SIGCHLD:
self._spawn_missing_workers()
else:
LOG.debug("unhandled signal %s" % sig)

Expand Down
7 changes: 2 additions & 5 deletions cotyledon/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ def __init__(self, master=False):
self._signals_received = collections.deque()

signal.signal(signal.SIGINT, signal.SIG_DFL)
signal.signal(signal.SIGCHLD, signal.SIG_DFL)
if os.name == 'posix':
signal.signal(signal.SIGTERM, self._signal_catcher)
signal.signal(signal.SIGALRM, self._signal_catcher)
Expand Down Expand Up @@ -144,7 +145,6 @@ def _wait_forever(self):
if os.name == "posix":
self._empty_signal_pipe()
self._run_signal_handlers()
self._on_wakeup()

if os.name == "posix":
# NOTE(sileht): we cannot use threading.Event().wait(),
Expand All @@ -157,7 +157,7 @@ def _wait_forever(self):
# That looks perfect to ensure handlers are run and run in the
# main thread
try:
select.select([self.signal_pipe_r], [], [], 0.5)
select.select([self.signal_pipe_r], [], [])
except select.error as e:
if e.args[0] != errno.EINTR:
raise
Expand All @@ -183,8 +183,5 @@ def _run_signal_handlers(self):
return
self._on_signal_received(sig)

def _on_wakeup(self):
pass

def _on_signal_received(self, sig):
pass

0 comments on commit 64fea67

Please sign in to comment.