Open Programmierus opened 2 years ago
To work around this issue, you might consider a few alternative approaches:
Use Regular asyncio
Event Loop: As you mentioned, the issue doesn't occur with the regular asyncio
loop. If this is acceptable for your use case, you can consider sticking with the regular asyncio
event loop instead of using uvloop
.
Wrap socket
in a Context Manager: You can create a custom context manager that wraps the socket and ensures it's not prematurely closed. Here's an example of how you could do this:
import asyncio
import socket
import uvloop
from contextlib import contextmanager
b = bytes('{"msg": "test"}', 'utf-8')
@contextmanager
def open_socket():
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.connect('data/sockets/echo_server.sock')
yield sock
sock.close()
async def main_async(sock: socket.socket):
_, writer = await asyncio.open_unix_connection(sock=sock)
writer.write(b)
await writer.drain()
if __name__ == '__main__':
uvloop.install()
with open_socket() as sock:
asyncio.run(main_async(sock))
sock.sendall(b) # Should not result in "OSError: [Errno 9] Bad file descriptor"
Using a context manager ensures that the socket is properly closed when you're done with it, avoiding potential issues with the socket's lifecycle.
uvloop
, asyncio
, and other relevant libraries. If the issue is a known bug, there might be a fix available in newer versions.
This seem to be version/OS unrelated. Sample:
Last line result in exception "OSError: [Errno 9] Bad file descriptor" because sock gets closed right after asyncio.run() terminates. It is wrong behavior, because sock was created outside of asyncio loop and has to be left untouched. The issue doesn't occur using regular asyncio loop.