In developing a new feature in ChemMine, I encountered the problem of daemonizing a python script, for a second time.
Typically a HTTP request can be handled pretty fast. So unless I need to call some C or C-based code that can potentially crash the server, I would just process it inside the server process. For these C and C-based code, I would call it using os.system(...). But when the external process takes very long time, the python-based application server will wait and wait, and finally the client will timeout the request.
That’s why I need to daemonize these time-consuming processes, or in other words, run them in the “background” so that the application server can respond the client ASAP. Daemonizing them looks easy at the beginning, and there is a recipe for that purpose. The thing is that it makes it really hard to debug. Sometimes when you test it inside a terminal, it returns instantly just as it is successfully daemonized; but when you test it in the application server you would find the server will still wait for it to finish. So here is the most important thing to remember when you daemonize a process: close ALL fd’s at the OS level, that is, call os.close(...) to close fd from 0 up to 1023.
That would also makes it impossible to debug, because the standard output and error are also closed, and all error messages are discarded. So I would leave the standard error to open, until I iron out all the bugs.
Also, if you call further external programs in this daemonized processing using services like os.system(...), make sure you redirect their standard output and standard error. These are not available in the daemonized process, and the spawned process from it will not be able to inherit them and can potentially die when it fails to write something.