Skip to content

Commit 856b31e

Browse files
committed
Add docs
1 parent dab5212 commit 856b31e

File tree

2 files changed

+106
-4
lines changed

2 files changed

+106
-4
lines changed

Doc/library/asyncio-protocol.rst

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,16 @@ Protocol classes
333333
The base class for implementing streaming protocols (for use with
334334
e.g. TCP and SSL transports).
335335

336+
.. class:: BufferedProtocol
337+
338+
A base class for implementing streaming protocols with manual
339+
control of the receive buffer.
340+
341+
.. versionadded:: 3.7
342+
**Important:** this has been been added to asyncio in Python 3.7
343+
*on a provisional basis*! Treat it as an experimental API that
344+
might be changed or removed in Python 3.8.
345+
336346
.. class:: DatagramProtocol
337347

338348
The base class for implementing datagram protocols (for use with
@@ -428,9 +438,66 @@ and, if called, :meth:`data_received` won't be called after it.
428438

429439
State machine:
430440

441+
.. code-block:: none
442+
443+
start -> :meth:`~BaseProtocol.connection_made`
444+
[-> :meth:`~Protocol.data_received`]*
445+
[-> :meth:`~Protocol.eof_received`]?
446+
-> :meth:`~BaseProtocol.connection_lost` -> end
447+
448+
449+
Streaming protocols with manual receive buffer control
450+
------------------------------------------------------
451+
452+
.. versionadded:: 3.7
453+
**Important:** :class:`BufferedProtocol` has been been added to
454+
asyncio in Python 3.7 *on a provisional basis*! Treat it as an
455+
experimental API that might be changed or removed in Python 3.8.
456+
457+
458+
Event methods, such as :meth:`AbstractEventLoop.create_server` and
459+
:meth:`AbstractEventLoop.create_connection`, accept factories that
460+
return protocols that implement this interface.
461+
462+
The idea of BufferedProtocol is that it allows to manually allocate
463+
and control the receive buffer. Event loops can then use the buffer
464+
provided by the protocol to avoid unnecessary data copies. This
465+
can result in noticeable performance improvement for protocols that
466+
receive big amounts of data. Sophisticated protocols can allocate
467+
the buffer only once at creation time.
468+
469+
The following callbacks are called on :class:`BufferedProtocol`
470+
instances:
471+
472+
.. method:: BufferedProtocol.get_buffer()
473+
474+
Called to allocate a new receive buffer. Must return an object
475+
that implements the :ref:`buffer protocol <bufferobjects>`.
476+
477+
.. method:: BufferedProtocol.buffer_updated(nbytes)
478+
479+
Called when the buffer was updated with the received data.
480+
481+
*nbytes* is the total number of bytes that were written to the buffer.
482+
483+
.. method:: BufferedProtocol.eof_received()
484+
485+
See the documentation of the :meth:`Protocol.eof_received` method.
486+
487+
488+
:meth:`get_buffer` can be called an arbitrary number of times during
489+
a connection. However, :meth:`eof_received` is called at most once
490+
and, if called, :meth:`data_received` won't be called after it.
491+
492+
State machine:
493+
494+
.. code-block:: none
495+
431496
start -> :meth:`~BaseProtocol.connection_made`
432-
[-> :meth:`~Protocol.data_received` \*]
433-
[-> :meth:`~Protocol.eof_received` ?]
497+
[-> :meth:`~BufferedProtocol.get_buffer`
498+
[-> :meth:`~BufferedProtocol.buffer_updated`]?
499+
]*
500+
[-> :meth:`~Protocol.eof_received`]?
434501
-> :meth:`~BaseProtocol.connection_lost` -> end
435502
436503

Lib/asyncio/protocols.py

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,46 @@ def eof_received(self):
103103

104104

105105
class BufferedProtocol(BaseProtocol):
106+
"""Interface for stream protocol with manual buffer control.
107+
108+
Important: this has been been added to asyncio in Python 3.7
109+
*on a provisional basis*! Treat it as an experimental API that
110+
might be changed or removed in Python 3.8.
111+
112+
Event methods, such as `create_server` and `create_connection`,
113+
accept factories that return protocols that implement this interface.
114+
115+
The idea of BufferedProtocol is that it allows to manually allocate
116+
and control the receive buffer. Event loops can then use the buffer
117+
provided by the protocol to avoid unnecessary data copies. This
118+
can result in noticeable performance improvement for protocols that
119+
receive big amounts of data. Sophisticated protocols can allocate
120+
the buffer only once at creation time.
121+
122+
State machine of calls:
123+
124+
start -> CM [-> GB [-> BU?]]* [-> ER?] -> CL -> end
125+
126+
* CM: connection_made()
127+
* GB: get_buffer()
128+
* BU: buffer_updated()
129+
* ER: eof_received()
130+
* CL: connection_lost()
131+
"""
132+
106133
def get_buffer(self):
107-
raise NotImplementedError
134+
"""Called to allocate a new receive buffer.
135+
136+
Must return an object that implements the
137+
:ref:`buffer protocol <bufferobjects>`.
138+
"""
108139

109140
def buffer_updated(self, nbytes):
110-
pass
141+
"""Called when the buffer was updated with the received data.
142+
143+
*nbytes* is the total number of bytes that were written to
144+
the buffer.
145+
"""
111146

112147
def eof_received(self):
113148
"""Called when the other end calls write_eof() or equivalent.

0 commit comments

Comments
 (0)