Skip to content

Commit 9e5b91b

Browse files
committed
Improve documentation of latency.
Also fix #1414.
1 parent 8eaa5a2 commit 9e5b91b

File tree

4 files changed

+32
-16
lines changed

4 files changed

+32
-16
lines changed

docs/reference/features.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ Both sides
5959
+------------------------------------+--------+--------+--------+--------+
6060
| Heartbeat |||||
6161
+------------------------------------+--------+--------+--------+--------+
62+
| Measure latency |||||
63+
+------------------------------------+--------+--------+--------+--------+
6264
| Perform the closing handshake |||||
6365
+------------------------------------+--------+--------+--------+--------+
6466
| Enforce closing timeout |||||

docs/topics/keepalive.rst

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,21 +40,24 @@ It loops through these steps:
4040
If the Pong frame isn't received, websockets considers the connection broken and
4141
closes it.
4242

43-
This mechanism serves two purposes:
43+
This mechanism serves three purposes:
4444

4545
1. It creates a trickle of traffic so that the TCP connection isn't idle and
4646
network infrastructure along the path keeps it open ("keepalive").
4747
2. It detects if the connection drops or becomes so slow that it's unusable in
4848
practice ("heartbeat"). In that case, it terminates the connection and your
4949
application gets a :exc:`~exceptions.ConnectionClosed` exception.
50+
3. It measures the :attr:`~asyncio.connection.Connection.latency` of the
51+
connection. The time between sending a Ping frame and receiving a matching
52+
Pong frame approximates the round-trip time.
5053

5154
Timings are configurable with the ``ping_interval`` and ``ping_timeout``
5255
arguments of :func:`~asyncio.client.connect` and :func:`~asyncio.server.serve`.
5356
Shorter values will detect connection drops faster but they will increase
5457
network traffic and they will be more sensitive to latency.
5558

5659
Setting ``ping_interval`` to :obj:`None` disables the whole keepalive and
57-
heartbeat mechanism.
60+
heartbeat mechanism, including measurement of latency.
5861

5962
Setting ``ping_timeout`` to :obj:`None` disables only timeouts. This enables
6063
keepalive, to keep idle connections open, and disables heartbeat, to support large
@@ -85,9 +88,23 @@ Unfortunately, the WebSocket API in browsers doesn't expose the native Ping and
8588
Pong functionality in the WebSocket protocol. You have to roll your own in the
8689
application layer.
8790

91+
Read this `blog post <https://making.close.com/posts/reliable-websockets/>`_ for
92+
a complete walk-through of this issue.
93+
8894
Latency issues
8995
--------------
9096

97+
The :attr:`~asyncio.connection.Connection.latency` attribute stores latency
98+
measured during the last exchange of Ping and Pong frames::
99+
100+
latency = websocket.latency
101+
102+
Alternatively, you can measure the latency at any time by calling
103+
:attr:`~asyncio.connection.Connection.ping` and awaiting its result::
104+
105+
pong_waiter = await websocket.ping()
106+
latency = await pong_waiter
107+
91108
Latency between a client and a server may increase for two reasons:
92109

93110
* Network connectivity is poor. When network packets are lost, TCP attempts to
@@ -97,7 +114,7 @@ Latency between a client and a server may increase for two reasons:
97114

98115
* Traffic is high. For example, if a client sends messages on the connection
99116
faster than a server can process them, this manifests as latency as well,
100-
because data is waiting in flight, mostly in OS buffers.
117+
because data is waiting in :doc:`buffers <memory>`.
101118

102119
If the server is more than 20 seconds behind, it doesn't see the Pong before
103120
the default timeout elapses. As a consequence, it closes the connection.
@@ -109,8 +126,3 @@ Latency between a client and a server may increase for two reasons:
109126

110127
The same reasoning applies to situations where the server sends more traffic
111128
than the client can accept.
112-
113-
The latency measured during the last exchange of Ping and Pong frames is
114-
available in the :attr:`~asyncio.connection.Connection.latency` attribute.
115-
Alternatively, you can measure the latency at any time with the
116-
:attr:`~asyncio.connection.Connection.ping` method.

src/websockets/asyncio/connection.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,13 @@ def __init__(
109109
"""
110110
Latency of the connection, in seconds.
111111
112-
This value is updated after sending a ping frame and receiving a
113-
matching pong frame. Before the first ping, :attr:`latency` is ``0``.
112+
Latency is defined as the round-trip time of the connection. It is
113+
measured by sending a Ping frame and waiting for a matching Pong frame.
114+
Before the first measurement, :attr:`latency` is ``0``.
114115
115116
By default, websockets enables a :ref:`keepalive <keepalive>` mechanism
116-
that sends ping frames automatically at regular intervals. You can also
117-
send ping frames and measure latency with :meth:`ping`.
117+
that sends Ping frames automatically at regular intervals. You can also
118+
send Ping frames and measure latency with :meth:`ping`.
118119
"""
119120

120121
# Task that sends keepalive pings. None when ping_interval is None.

src/websockets/legacy/protocol.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -289,12 +289,13 @@ def __init__(
289289
"""
290290
Latency of the connection, in seconds.
291291
292-
This value is updated after sending a ping frame and receiving a
293-
matching pong frame. Before the first ping, :attr:`latency` is ``0``.
292+
Latency is defined as the round-trip time of the connection. It is
293+
measured by sending a Ping frame and waiting for a matching Pong frame.
294+
Before the first measurement, :attr:`latency` is ``0``.
294295
295296
By default, websockets enables a :ref:`keepalive <keepalive>` mechanism
296-
that sends ping frames automatically at regular intervals. You can also
297-
send ping frames and measure latency with :meth:`ping`.
297+
that sends Ping frames automatically at regular intervals. You can also
298+
send Ping frames and measure latency with :meth:`ping`.
298299
"""
299300

300301
# Task running the data transfer.

0 commit comments

Comments
 (0)