Can't close properly a tango server
Hi,
I was trying to do some test coverage on a tango server wrtiten in python.
proc = subprocess to server
... do some stuffs ...
proc.terminate()
I found out actually SIGTERM do not terminate the python interpreter properly.
Basically the running event loop looks to be not interrupted, but instead the process is killed.
As result the coverage information is not stored properly, because atexit is not triggered.
I have also noticed that if you launch a tango server on a shell with introspection code at the termination (print("end")).
If you press CTRL-C, your introspection code is not triggered.
I think that's the same problem.
Here is my work around for now, which is very fragile.
def patch_gevent_executor():
"""
Enforce a better termination of the python process with `SIGTERM`.
This patch `run` with a `wait=False`. The wait is postponed in a greenlet
to be able to interrupt it. Finally, at the termination of the process,
a `SIGQUIT` is emitted to skip waiting of remaining tasks.
"""
from tango.gevent_executor import GeventExecutor
old_run = GeventExecutor.run
def run(self: GeventExecutor, fn, args=(), kwargs={}, wait=None, timeout=None):
accessor = old_run(self, fn, wait=False)
g = gevent.spawn(accessor.get)
def stop_server():
nonlocal g
g.kill(block=False)
gevent.signal_handler(signal.SIGINT, stop_server)
gevent.signal_handler(signal.SIGTERM, stop_server)
g.get()
import os
import atexit
def quit_python():
os.kill(os.getpid(), signal.SIGQUIT)
# Ultimately force to quit the interpreter else it stuck
atexit.register(quit_python)
GeventExecutor.run = run
With that i can execute the server
patch_gevent_executor()
main(args)
I was testing that code with the databaseds server, but it's probably the same for other python servers.
Do you have any idea if it could be possible to close properly a server? Basically request to interrupt the event loop? I could already simplify a lot that patch if it could be possible.