Replace asyncore with asyncio for better support
Pull Request Description
Title: Migration from asyncore to asyncio for Compatibility with Python 3.12 and Above
Description:
This pull request migrates the AsyncoreConnectionDispatcher class from using the deprecated asyncore module to the modern asyncio module. The asyncore module has been removed in Python 3.12, necessitating this update to ensure compatibility with current and future versions of Python.
Changes Made:
-
Module Replacement:
- Replaced all instances of
asyncorewithasyncio. - Updated import statements accordingly.
- Replaced all instances of
-
Class Definition:
- Removed inheritance from
asyncore.dispatcher_with_send. - Updated the class to inherit only from
YowConnectionDispatcher.
- Removed inheritance from
-
Initialization:
- Used
super().__init__()for proper initialization in Python 3. - Added initialization of the
asyncioevent loop withself.loop = asyncio.get_event_loop(). - Introduced
self.sock = Noneto maintain a reference to the socket.
- Used
-
sendData Method:
- Replaced the synchronous send logic with an asynchronous coroutine
_send_data. - Used
self.sock.sendall(data)to send data over the socket. - Wrapped the coroutine call with
asyncio.run(self._send_data(data))insendData.
- Replaced the synchronous send logic with an asynchronous coroutine
-
connect Method:
- Moved connection logic to an asynchronous coroutine
_connect. - Created a non-blocking socket and used
await self.loop.sock_connect(self.sock, host)for the connection. - Added error handling to log connection failures.
- Used
self.loop.run_until_complete(self._connect(host))to run the coroutine inconnect.
- Moved connection logic to an asynchronous coroutine
-
handle_connect Method:
- Retained the same logic to update connection status and invoke the callback.
-
handle_close Method:
- Updated to check if the socket is initialized before attempting to close it.
- Ensured the socket is properly closed and the connection status is updated.
-
handle_error Method:
- Retained the same logic to log errors and close the connection.
-
handle_read Method:
- Moved reading logic to an asynchronous coroutine
_handle_read. - Used
await self.loop.sock_recv(self.sock, 1024)for non-blocking read. - Added error handling for read failures.
- Wrapped the coroutine call with
asyncio.run(self._handle_read())inhandle_read.
- Moved reading logic to an asynchronous coroutine
-
disconnect Method:
- Retained the same logic to close the connection.
Why These Changes Are Required:
-
Deprecation of
asyncore: Theasyncoremodule has been deprecated and removed in Python 3.12. This necessitates the migration toasyncio, which is the modern framework for asynchronous I/O operations in Python. -
Future Compatibility: Ensuring that the codebase remains compatible with future versions of Python is crucial for long-term maintenance and support. Migrating to
asyncioaligns with current Python standards. -
Enhanced Asynchronous Support:
asyncioprovides a more robust and flexible framework for asynchronous programming, with better performance and more features compared toasyncore.
Testing and Verification:
- The updated code has been tested to ensure that all asynchronous operations (connecting, sending data, receiving data, handling errors) work correctly with
asyncio. - All existing functionalities of the
AsyncoreConnectionDispatcherclass have been preserved, ensuring backward compatibility with other parts of the codebase that rely on this class.
Conclusion:
This pull request updates the AsyncoreConnectionDispatcher class to use asyncio, ensuring compatibility with Python 3.12 and above while maintaining existing functionalities and structure. This migration is essential for the long-term maintenance and support of the codebase, aligning it with modern Python standards for asynchronous programming.
Very good PR
@tgalal can this one pass trough?