Skip to content

Instantly share code, notes, and snippets.

@eugene-bright
Created October 17, 2018 14:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eugene-bright/31b46aba9929ff1d4e07ceb98dc0b07d to your computer and use it in GitHub Desktop.
Save eugene-bright/31b46aba9929ff1d4e07ceb98dc0b07d to your computer and use it in GitHub Desktop.
Wait for tcp service
import socket
from typing import Callable
from linuxfd import timerfd
from itertools import (
starmap,
repeat,
)
def wait_for_tcp_service(
addr: str,
port: int,
*,
timeout: float=5.0,
interval: float=0.1,
tcp_timeout_calc: Callable[[float], float] =
lambda t: 1 if t > 1 else t
):
if interval <= 0:
raise TypeError("interval value must be positive")
tfd = timerfd()
tfd.settime(interval, interval)
err_msg = f"Can't establish connection to {addr}:{port}"
elapsed = 0
err: Exception
with socket.socket() as s:
try:
# try to fight exploding retransmision time
s.settimeout(tcp_timeout_calc(timeout))
s.connect((addr, port))
except socket.error as e:
err = e
else:
return
with socket.socket() as s:
for i in starmap(tfd.read, repeat([])):
elapsed += i * interval
if elapsed >= timeout and err:
raise TimeoutError(err_msg) from err
try:
remaining = timeout - elapsed
s.settimeout(tcp_timeout_calc(remaining))
s.connect((addr, port))
except socket.error as e:
err = e
else:
return
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment