So I'm writing a script/application that uses pythons multiprocessing BaseManager class. Now for the most part it works great, the only issue I have is that I am using the serve_forever
as a blocking statement and then continue onwards however when I want to terminate or exit out of the serve_forever()
function(ality) it automatically exits out and terminates the application, but like I mentioned I have some more things I want to take care of before I completely exit out.
I can exit out of serve_forever()
by setting a stop event with stop_event.set()
. Now this is all well and dandy however according to the source (https://github.com/python/cpython/blob/3.6/Lib/multiprocessing/managers.py#L147) serve_forever
explicitly states sys.exit(0)
and is part of the Server
class that BaseManager
uses within it's definition. Essentially I would like to remove that line (sys.exit(0)
). How would I accompolish this?
When I search I'm coming up with results such as monkey patching? Can I just Subclass the Server class, explicitly define serve_forever
to be the exact same code but without the sys.exit(0)
line and call it a day? Something tells me that is not going to work. Do I subclass Server AND BaseManager?
Thanks!
CodePudding user response:
Attempting to monkey-patch or inherit internal classes will result in code that will not be compatible across Python releases, not even patches.
Atop of that, these solutions will be unnecessarily complex and complicated, and are overall frowned upon.
I highly suggest re-implementing serve_forever()
by using the start()
method together with an event. Waiting for the event to be called or, if impossible, a loop checking if the manager is still alive, will be much easier and a better solution in almost all aspects that I can think of.
After discussing in chat, we realised the easiest approach is to just suppress the SystemExit
being thrown from sys.exit()
. I'm opening a bug report on CPython bug tracker accordingly to prevent sys.exit()
. Do keep in mind the server will not actually shut down as it is run on a different thread. The whole recommendation of using .server().serve_forever()
in the stdlib looks dubious at best.
If you wish to immediately shut down the server, call Server.listener.close()
after catcing the exception.