Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add TCP keepalive option for asyncio.start_server() #101336

Closed
beavailable opened this issue Jan 26, 2023 · 3 comments
Closed

Add TCP keepalive option for asyncio.start_server() #101336

beavailable opened this issue Jan 26, 2023 · 3 comments
Labels
topic-asyncio type-feature A feature request or enhancement

Comments

@beavailable
Copy link
Contributor

beavailable commented Jan 26, 2023

By default, this asyncio.start_server() method will create a list of socket objects usually for both IPv4 and IPv6 (if possible) and do not set keepalive option. if I want I can create a socket object by myself and set keepalive option for it, then pass it in start_server(), but if so, I will not be able to start a server which listens on both IPv4 and IPv6 addresses.
I hope we can add a keepalive parameter for asyncio.start_server() or do something else to make things easier.

Linked PRs

@axoroll7
Copy link

axoroll7 commented Aug 15, 2023

I don't have the same problem as you, but I understand your problem. It is a recurrent problem for me. For many projects, not only web servers, but others TCP servers too. The same problem appears with others programming languages. To alleviate this problem in Python, I thought about monkey-patching the library in question, or the socket library to use TCP keepalive. The mode being applied before bind and connect. Can TCP keepalive be applied after bind, connect or the first interaction ? In addition to this, it is difficult to access the internal sockets.

For some software prototypes, (never in production), I patched some methods of the socket object to add TCP keepalive, for most OSes :

Function signature :

def tcp_keepalive(
        sock:socket.socket,
        idle:int,
        interval:int,
        max:Optional[None] = None,
    ) -> None:
    pass

For linux :

sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, idle)
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, interval)
if max is not None:
    sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, max)

For BSD (macOS, FreeBSD, OpenBSD, NetBSD) :

# BSD offers only one parameter
TCP_KEEPALIVE = 0x10
sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
sock.setsockopt(socket.IPPROTO_TCP, TCP_KEEPALIVE, idle)

For Windows :

# max is not configurable on Windows
sock.ioctl(socket.SIO_KEEPALIVE_VALS, (1, idle * 1000, interval * 1000))

(English isn't my first language, so please excuse any mistakes.)

@beavailable
Copy link
Contributor Author

Can TCP keepalive be applied after bind, connect or the first interaction ?

Seems that it can't.

@iritkatriel iritkatriel added topic-asyncio type-feature A feature request or enhancement labels Nov 27, 2023
@gvanrossum
Copy link
Member

Please just propose a pull request that adds a keyword parameter to the right API. We will take it from there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic-asyncio type-feature A feature request or enhancement
Projects
Status: Done
Development

No branches or pull requests

4 participants