eventloop: add async create socket method
Signed-off-by: Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
parent
371840a988
commit
0b31d7d0b2
|
@ -8,12 +8,14 @@ from __future__ import annotations
|
||||||
import asyncio
|
import asyncio
|
||||||
import inspect
|
import inspect
|
||||||
import functools
|
import functools
|
||||||
|
import socket
|
||||||
from typing import (
|
from typing import (
|
||||||
TYPE_CHECKING,
|
TYPE_CHECKING,
|
||||||
Awaitable,
|
Awaitable,
|
||||||
Callable,
|
Callable,
|
||||||
Coroutine,
|
Coroutine,
|
||||||
Optional,
|
Optional,
|
||||||
|
Tuple,
|
||||||
TypeVar,
|
TypeVar,
|
||||||
Union
|
Union
|
||||||
)
|
)
|
||||||
|
@ -83,6 +85,45 @@ class EventLoop:
|
||||||
) -> Awaitable[_T]:
|
) -> Awaitable[_T]:
|
||||||
return self.aioloop.run_in_executor(None, callback, *args)
|
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):
|
def start(self):
|
||||||
self.aioloop.run_forever()
|
self.aioloop.run_forever()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue