nickstenning / honcho

Honcho: a python clone of Foreman. For managing Procfile-based applications.
http://pypi.python.org/pypi/honcho
MIT License
1.59k stars 145 forks source link

Get rid of defunct processes when using honcho in a docker context #186

Open mostowski opened 7 years ago

mostowski commented 7 years ago

Hi,

I use honcho as entrypoint in a docker context to manage multi-services docker container. It works fine, however in some cases of use, it creates defunct processes.

To get rid of that, I modified the method Manager.loop to act as init, for waiting zombie processes to terminate, if honcho has pid 1.

Nota : I used an old version of psutil (0.6.1) module, because I am working on RHEL6 and I used standard rpm package.

Here is the diff patch :

--- manager.py  2016-09-28 15:56:52.781413761 +0200
+++ ../../../poc_with_barman/build/manager.py   2016-10-03 17:16:33.181063987 +0200
@@ -1,3 +1,6 @@
+import psutil
+import os
+
 import datetime
 import multiprocessing
 import signal
@@ -97,9 +100,34 @@
             self.returncode = SIGNALS[signum]['rc']
             self.terminate()

+        """
+        If pid=1 honcho act as init processus and must wait for orphean
+        process to avoid zombie.
+        This is usefull when you use honcho as entrypoint in docker image.
+        """
+        def _wait_zombie():
+                for proc in psutil.process_iter():
+                        try:
+                               if proc.status == psutil.STATUS_ZOMBIE:
+                                       proc.wait(timeout=KILL_WAIT)
+                        except psutil.NoSuchProcess:
+                                pass
+
+        """
+        When SIGCHLD is receive call _wait_zombie to get rid of defunct
+        """
+       def _sig_chld(signum, frame):
+                _wait_zombie()
+
         signal.signal(signal.SIGTERM, _terminate)
         signal.signal(signal.SIGINT, _terminate)

+        """
+        If pid=1 init call back _sig_chld to get rid of defunct
+        """
+        if os.getpid() == 1:
+                signal.signal(signal.SIGCHLD, _sig_chld)
+
         self._start()

         exit = False
alanjds commented 4 years ago

Questions: 1) This issue is from 2016. Is still valid? 2) Is Honcho able to honor the responsibility of being PID 1 now? I mean, it needs tini wrapper or something like this, or is good to go alone?