eventloop: add async create socket method

Signed-off-by:  Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
Eric Callahan 2022-06-28 14:34:47 -04:00
parent 371840a988
commit 0b31d7d0b2
No known key found for this signature in database
GPG Key ID: 5A1EB336DFB4C71B
1 changed files with 41 additions and 0 deletions

View File

@ -8,12 +8,14 @@ from __future__ import annotations
import asyncio
import inspect
import functools
import socket
from typing import (
TYPE_CHECKING,
Awaitable,
Callable,
Coroutine,
Optional,
Tuple,
TypeVar,
Union
)
@ -83,6 +85,45 @@ class EventLoop:
) -> Awaitable[_T]:
return self.aioloop.run_in_executor(None, callback, *args)
async def create_socket_connection(
self, address: Tuple[str, int], timeout: Optional[float] = None
) -> socket.socket:
host, port = address
"""
async port of socket.create_connection()
"""
loop = self.aioloop
err = None
ainfo = await loop.getaddrinfo(
host, port, family=0, type=socket.SOCK_STREAM
)
for res in ainfo:
af, socktype, proto, canonname, sa = res
sock = None
try:
sock = socket.socket(af, socktype, proto)
sock.settimeout(0)
sock.setblocking(False)
await asyncio.wait_for(
loop.sock_connect(sock, (host, port)), timeout
)
# Break explicitly a reference cycle
err = None
return sock
except (socket.error, asyncio.TimeoutError) as _:
err = _
if sock is not None:
loop.remove_writer(sock.fileno())
sock.close()
if err is not None:
try:
raise err
finally:
# Break explicitly a reference cycle
err = None
else:
raise socket.error("getaddrinfo returns an empty list")
def start(self):
self.aioloop.run_forever()