I'm using the python-daemon package to create a daemon.
Here is a sample of what I'm doing:
def main():
import daemon
import os
here = os.path.dirname(os.path.abspath(__file__))
out = open("debug.log", "w+")
with daemon.DaemonContext(working_directory=here, stdout=out):
import asyncio
def handle_client(reader, writer):
print("client connected")
async def run():
server = await asyncio.start_server(
handle_client, "0.0.0.0", 5555, start_serving=True
)
print("Listening")
async with server:
await server.serve_forever()
loop = asyncio.get_event_loop()
loop.run_until_complete(run())
if __name__ == "__main__":
main()
So theres 2 ways to run it... by calling the file directly, or by importing the main function and calling it.
It works one way... but not the other.
If I run it like this it works:
python <filenameabove>
However, I'm trying to run this from another python file:
from packagename.otherfile import main
main()
That doesn't work... I get the following error when looking at stderr:
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/base_events.py", line 629, in run_until_complete
self.run_forever()
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/base_events.py", line 596, in run_forever
self._run_once()
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/base_events.py", line 1854, in _run_once
event_list = self._selector.select(timeout)
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/selectors.py", line 562, in select
kev_list = self._selector.control(None, max_ev, timeout)
OSError: [Errno 9] Bad file descriptor
As mentioned in one of the comments, this approach is old and there are better ways to do it. I've since moved to using a process supervisor and all is well.
This still bugged me though.
After doing a bit more research, I found the culprit.
I changed this to:
and it works! I thought importing asyncio after the fork would have been fine but needed a new event loop