When starting a python application, our application may wait for a server to respond.
This article introduce a common technique to wait for a server to be available using socket
from python stdlib. A script may wait for a database to start or for an API to become available.
I have written wait_port
, the following function, for the open source library fixtup
. fixtup
starts containers so that a test can run. There is a need to wait before returning control or executing migration code until the container is operational. The wait_port
helper allows you to wait in a hook before returning control to pytest.
# wait postgresql to start until 5 seconds or raise Timeout exception
wait_port(5432, timeout=5000)
here is the snippet you can reuse in your project
def wait_port(port: int, host: str = 'localhost', timeout: Optional[int] = None, attempt_every: int = 100) -> None:
"""
wait until a port would be open, for example the port 5432 for postgresql
before going further
>>> fixtup.helper.wait_port(5432, timeout=5000)
:param port: port that has to be open
:param remote_ip: host on which the port has to be open. It will be localhost by default
:param timeout: timeout in ms before raising TimeoutError.
:param attempt_every: time in ms between each attempt to check if the port is responding
"""
start = monotonic()
connected = False
while not connected:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
try:
s.connect((host, port))
connected = True
except ConnectionRefusedError:
if timeout is not None and monotonic() - start > (timeout / 1000):
raise TimeoutError()
sleep(attempt_every / 1000)
We can go further with the principle of this snippet. It can be used to verify that a database is ready for use by checking for the existence of a table or by executing a SELECT 1 + 1
query instead of connecting with a socket.
If you had to write resilient code to wait for a server, share your experience with us in the comments.
Top comments (0)