Skip to content

Commit 50b6d20

Browse files
committed
Various cleanups in sync implementation.
1 parent de768cf commit 50b6d20

File tree

3 files changed

+45
-49
lines changed

3 files changed

+45
-49
lines changed

src/websockets/sync/client.py

+4-5
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
class ClientConnection(Connection):
2727
"""
28-
Threaded implementation of a WebSocket client connection.
28+
:mod:`threading` implementation of a WebSocket client connection.
2929
3030
:class:`ClientConnection` provides :meth:`recv` and :meth:`send` methods for
3131
receiving and sending messages.
@@ -157,7 +157,7 @@ def connect(
157157
158158
:func:`connect` may be used as a context manager::
159159
160-
async with websockets.sync.client.connect(...) as websocket:
160+
with websockets.sync.client.connect(...) as websocket:
161161
...
162162
163163
The connection is closed automatically when exiting the context.
@@ -273,19 +273,18 @@ def connect(
273273
sock = ssl.wrap_socket(sock, server_hostname=server_hostname)
274274
sock.settimeout(None)
275275

276-
# Initialize WebSocket connection
276+
# Initialize WebSocket protocol
277277

278278
protocol = ClientProtocol(
279279
wsuri,
280280
origin=origin,
281281
extensions=extensions,
282282
subprotocols=subprotocols,
283-
state=CONNECTING,
284283
max_size=max_size,
285284
logger=logger,
286285
)
287286

288-
# Initialize WebSocket protocol
287+
# Initialize WebSocket connection
289288

290289
connection = create_connection(
291290
sock,

src/websockets/sync/connection.py

+28-30
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,10 @@
2121

2222
__all__ = ["Connection"]
2323

24-
logger = logging.getLogger(__name__)
25-
2624

2725
class Connection:
2826
"""
29-
Threaded implementation of a WebSocket connection.
27+
:mod:`threading` implementation of a WebSocket connection.
3028
3129
:class:`Connection` provides APIs shared between WebSocket servers and
3230
clients.
@@ -82,15 +80,15 @@ def __init__(
8280
self.close_deadline: Optional[Deadline] = None
8381

8482
# Mapping of ping IDs to pong waiters, in chronological order.
85-
self.pings: Dict[bytes, threading.Event] = {}
83+
self.ping_waiters: Dict[bytes, threading.Event] = {}
8684

8785
# Receiving events from the socket.
8886
self.recv_events_thread = threading.Thread(target=self.recv_events)
8987
self.recv_events_thread.start()
9088

9189
# Exception raised in recv_events, to be chained to ConnectionClosed
9290
# in the user thread in order to show why the TCP connection dropped.
93-
self.recv_events_exc: Optional[BaseException] = None
91+
self.recv_exc: Optional[BaseException] = None
9492

9593
# Public attributes
9694

@@ -198,7 +196,7 @@ def recv(self, timeout: Optional[float] = None) -> Data:
198196
try:
199197
return self.recv_messages.get(timeout)
200198
except EOFError:
201-
raise self.protocol.close_exc from self.recv_events_exc
199+
raise self.protocol.close_exc from self.recv_exc
202200
except RuntimeError:
203201
raise RuntimeError(
204202
"cannot call recv while another thread "
@@ -229,9 +227,10 @@ def recv_streaming(self) -> Iterator[Data]:
229227
230228
"""
231229
try:
232-
yield from self.recv_messages.get_iter()
230+
for frame in self.recv_messages.get_iter():
231+
yield frame
233232
except EOFError:
234-
raise self.protocol.close_exc from self.recv_events_exc
233+
raise self.protocol.close_exc from self.recv_exc
235234
except RuntimeError:
236235
raise RuntimeError(
237236
"cannot call recv_streaming while another thread "
@@ -273,7 +272,7 @@ def send(self, message: Union[Data, Iterable[Data]]) -> None:
273272
274273
Raises:
275274
ConnectionClosed: When the connection is closed.
276-
RuntimeError: If a connection is busy sending a fragmented message.
275+
RuntimeError: If the connection is sending a fragmented message.
277276
TypeError: If ``message`` doesn't have a supported type.
278277
279278
"""
@@ -449,15 +448,15 @@ def ping(self, data: Optional[Data] = None) -> threading.Event:
449448

450449
with self.send_context():
451450
# Protect against duplicates if a payload is explicitly set.
452-
if data in self.pings:
451+
if data in self.ping_waiters:
453452
raise RuntimeError("already waiting for a pong with the same data")
454453

455454
# Generate a unique random payload otherwise.
456-
while data is None or data in self.pings:
455+
while data is None or data in self.ping_waiters:
457456
data = struct.pack("!I", random.getrandbits(32))
458457

459458
pong_waiter = threading.Event()
460-
self.pings[data] = pong_waiter
459+
self.ping_waiters[data] = pong_waiter
461460
self.protocol.send_ping(data)
462461
return pong_waiter
463462

@@ -504,22 +503,22 @@ def acknowledge_pings(self, data: bytes) -> None:
504503
"""
505504
with self.protocol_mutex:
506505
# Ignore unsolicited pong.
507-
if data not in self.pings:
506+
if data not in self.ping_waiters:
508507
return
509508
# Sending a pong for only the most recent ping is legal.
510509
# Acknowledge all previous pings too in that case.
511510
ping_id = None
512511
ping_ids = []
513-
for ping_id, ping in self.pings.items():
512+
for ping_id, ping in self.ping_waiters.items():
514513
ping_ids.append(ping_id)
515514
ping.set()
516515
if ping_id == data:
517516
break
518517
else:
519518
raise AssertionError("solicited pong not found in pings")
520-
# Remove acknowledged pings from self.pings.
519+
# Remove acknowledged pings from self.ping_waiters.
521520
for ping_id in ping_ids:
522-
del self.pings[ping_id]
521+
del self.ping_waiters[ping_id]
523522

524523
def recv_events(self) -> None:
525524
"""
@@ -541,18 +540,18 @@ def recv_events(self) -> None:
541540
self.logger.debug("error while receiving data", exc_info=True)
542541
# When the closing handshake is initiated by our side,
543542
# recv() may block until send_context() closes the socket.
544-
# In that case, send_context() already set recv_events_exc.
545-
# Calling set_recv_events_exc() avoids overwriting it.
543+
# In that case, send_context() already set recv_exc.
544+
# Calling set_recv_exc() avoids overwriting it.
546545
with self.protocol_mutex:
547-
self.set_recv_events_exc(exc)
546+
self.set_recv_exc(exc)
548547
break
549548

550549
if data == b"":
551550
break
552551

553552
# Acquire the connection lock.
554553
with self.protocol_mutex:
555-
# Feed incoming data to the connection.
554+
# Feed incoming data to the protocol.
556555
self.protocol.receive_data(data)
557556

558557
# This isn't expected to raise an exception.
@@ -568,7 +567,7 @@ def recv_events(self) -> None:
568567
# set by send_context(), in case of a race condition
569568
# i.e. send_context() closes the socket after recv()
570569
# returns above but before send_data() calls send().
571-
self.set_recv_events_exc(exc)
570+
self.set_recv_exc(exc)
572571
break
573572

574573
if self.protocol.close_expected():
@@ -595,7 +594,7 @@ def recv_events(self) -> None:
595594
# Breaking out of the while True: ... loop means that we believe
596595
# that the socket doesn't work anymore.
597596
with self.protocol_mutex:
598-
# Feed the end of the data stream to the connection.
597+
# Feed the end of the data stream to the protocol.
599598
self.protocol.receive_eof()
600599

601600
# This isn't expected to generate events.
@@ -609,7 +608,7 @@ def recv_events(self) -> None:
609608
# This branch should never run. It's a safety net in case of bugs.
610609
self.logger.error("unexpected internal error", exc_info=True)
611610
with self.protocol_mutex:
612-
self.set_recv_events_exc(exc)
611+
self.set_recv_exc(exc)
613612
# We don't know where we crashed. Force protocol state to CLOSED.
614613
self.protocol.state = CLOSED
615614
finally:
@@ -668,7 +667,6 @@ def send_context(
668667
wait_for_close = True
669668
# If the connection is expected to close soon, set the
670669
# close deadline based on the close timeout.
671-
672670
# Since we tested earlier that protocol.state was OPEN
673671
# (or CONNECTING) and we didn't release protocol_mutex,
674672
# it is certain that self.close_deadline is still None.
@@ -710,11 +708,11 @@ def send_context(
710708
# original_exc is never set when wait_for_close is True.
711709
assert original_exc is None
712710
original_exc = TimeoutError("timed out while closing connection")
713-
# Set recv_events_exc before closing the socket in order to get
711+
# Set recv_exc before closing the socket in order to get
714712
# proper exception reporting.
715713
raise_close_exc = True
716714
with self.protocol_mutex:
717-
self.set_recv_events_exc(original_exc)
715+
self.set_recv_exc(original_exc)
718716

719717
# If an error occurred, close the socket to terminate the connection and
720718
# raise an exception.
@@ -745,16 +743,16 @@ def send_data(self) -> None:
745743
except OSError: # socket already closed
746744
pass
747745

748-
def set_recv_events_exc(self, exc: Optional[BaseException]) -> None:
746+
def set_recv_exc(self, exc: Optional[BaseException]) -> None:
749747
"""
750-
Set recv_events_exc, if not set yet.
748+
Set recv_exc, if not set yet.
751749
752750
This method requires holding protocol_mutex.
753751
754752
"""
755753
assert self.protocol_mutex.locked()
756-
if self.recv_events_exc is None:
757-
self.recv_events_exc = exc
754+
if self.recv_exc is None:
755+
self.recv_exc = exc
758756

759757
def close_socket(self) -> None:
760758
"""

src/websockets/sync/server.py

+13-14
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030

3131
class ServerConnection(Connection):
3232
"""
33-
Threaded implementation of a WebSocket server connection.
33+
:mod:`threading` implementation of a WebSocket server connection.
3434
3535
:class:`ServerConnection` provides :meth:`recv` and :meth:`send` methods for
3636
receiving and sending messages.
@@ -188,6 +188,8 @@ class WebSocketServer:
188188
handler: Handler for one connection. Receives the socket and address
189189
returned by :meth:`~socket.socket.accept`.
190190
logger: Logger for this server.
191+
It defaults to ``logging.getLogger("websockets.server")``.
192+
See the :doc:`logging guide <../../topics/logging>` for details.
191193
192194
"""
193195

@@ -311,16 +313,16 @@ def serve(
311313
Whenever a client connects, the server creates a :class:`ServerConnection`,
312314
performs the opening handshake, and delegates to the ``handler``.
313315
314-
The handler receives a :class:`ServerConnection` instance, which you can use
315-
to send and receive messages.
316+
The handler receives the :class:`ServerConnection` instance, which you can
317+
use to send and receive messages.
316318
317319
Once the handler completes, either normally or with an exception, the server
318320
performs the closing handshake and closes the connection.
319321
320-
:class:`WebSocketServer` mirrors the API of
322+
This function returns a :class:`WebSocketServer` whose API mirrors
321323
:class:`~socketserver.BaseServer`. Treat it as a context manager to ensure
322-
that it will be closed and call the :meth:`~WebSocketServer.serve_forever`
323-
method to serve requests::
324+
that it will be closed and call :meth:`~WebSocketServer.serve_forever` to
325+
serve requests::
324326
325327
def handler(websocket):
326328
...
@@ -454,15 +456,13 @@ def conn_handler(sock: socket.socket, addr: Any) -> None:
454456
sock.do_handshake()
455457
sock.settimeout(None)
456458

457-
# Create a closure so that select_subprotocol has access to self.
458-
459+
# Create a closure to give select_subprotocol access to connection.
459460
protocol_select_subprotocol: Optional[
460461
Callable[
461462
[ServerProtocol, Sequence[Subprotocol]],
462463
Optional[Subprotocol],
463464
]
464465
] = None
465-
466466
if select_subprotocol is not None:
467467

468468
def protocol_select_subprotocol(
@@ -475,19 +475,18 @@ def protocol_select_subprotocol(
475475
assert protocol is connection.protocol
476476
return select_subprotocol(connection, subprotocols)
477477

478-
# Initialize WebSocket connection
478+
# Initialize WebSocket protocol
479479

480480
protocol = ServerProtocol(
481481
origins=origins,
482482
extensions=extensions,
483483
subprotocols=subprotocols,
484484
select_subprotocol=protocol_select_subprotocol,
485-
state=CONNECTING,
486485
max_size=max_size,
487486
logger=logger,
488487
)
489488

490-
# Initialize WebSocket protocol
489+
# Initialize WebSocket connection
491490

492491
assert create_connection is not None # help mypy
493492
connection = create_connection(
@@ -522,7 +521,7 @@ def protocol_select_subprotocol(
522521

523522

524523
def unix_serve(
525-
handler: Callable[[ServerConnection], Any],
524+
handler: Callable[[ServerConnection], None],
526525
path: Optional[str] = None,
527526
**kwargs: Any,
528527
) -> WebSocketServer:
@@ -541,4 +540,4 @@ def unix_serve(
541540
path: File system path to the Unix socket.
542541
543542
"""
544-
return serve(handler, path=path, unix=True, **kwargs)
543+
return serve(handler, unix=True, path=path, **kwargs)

0 commit comments

Comments
 (0)