summaryrefslogtreecommitdiffstats
path: root/Lib/asyncio
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2014-01-29 21:15:59 (GMT)
committerGuido van Rossum <guido@python.org>2014-01-29 21:15:59 (GMT)
commit3ccead1f6a36770b38c3fb561e74eb2e1dcbe76c (patch)
tree9b4e726a21dde3f5cdca221eed2d988242987554 /Lib/asyncio
parent63b4d4b494d57c90461740d0700af15ae4420618 (diff)
downloadcpython-3ccead1f6a36770b38c3fb561e74eb2e1dcbe76c.zip
cpython-3ccead1f6a36770b38c3fb561e74eb2e1dcbe76c.tar.gz
cpython-3ccead1f6a36770b38c3fb561e74eb2e1dcbe76c.tar.bz2
asyncio: Refactoring: move write flow control to a subclass/mixin.
Diffstat (limited to 'Lib/asyncio')
-rw-r--r--Lib/asyncio/selector_events.py98
1 files changed, 61 insertions, 37 deletions
diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py
index 94408f8..3690145 100644
--- a/Lib/asyncio/selector_events.py
+++ b/Lib/asyncio/selector_events.py
@@ -339,7 +339,67 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop):
sock.close()
-class _SelectorTransport(transports.Transport):
+class _FlowControlMixin(transports.Transport):
+ """All the logic for (write) flow control in a mix-in base class.
+
+ The subclass must implement get_write_buffer_size(). It must call
+ _maybe_pause_protocol() whenever the write buffer size increases,
+ and _maybe_resume_protocol() whenever it decreases. It may also
+ override set_write_buffer_limits() (e.g. to specify different
+ defaults).
+
+ The subclass constructor must call super().__init__(extra). This
+ will call set_write_buffer_limits().
+
+ The user may call set_write_buffer_limits() and
+ get_write_buffer_size(), and their protocol's pause_writing() and
+ resume_writing() may be called.
+ """
+
+ def __init__(self, extra=None):
+ super().__init__(extra)
+ self._protocol_paused = False
+ self.set_write_buffer_limits()
+
+ def _maybe_pause_protocol(self):
+ size = self.get_write_buffer_size()
+ if size <= self._high_water:
+ return
+ if not self._protocol_paused:
+ self._protocol_paused = True
+ try:
+ self._protocol.pause_writing()
+ except Exception:
+ logger.exception('pause_writing() failed')
+
+ def _maybe_resume_protocol(self):
+ if (self._protocol_paused and
+ self.get_write_buffer_size() <= self._low_water):
+ self._protocol_paused = False
+ try:
+ self._protocol.resume_writing()
+ except Exception:
+ logger.exception('resume_writing() failed')
+
+ def set_write_buffer_limits(self, high=None, low=None):
+ if high is None:
+ if low is None:
+ high = 64*1024
+ else:
+ high = 4*low
+ if low is None:
+ low = high // 4
+ if not high >= low >= 0:
+ raise ValueError('high (%r) must be >= low (%r) must be >= 0' %
+ (high, low))
+ self._high_water = high
+ self._low_water = low
+
+ def get_write_buffer_size(self):
+ raise NotImplementedError
+
+
+class _SelectorTransport(_FlowControlMixin, transports.Transport):
max_size = 256 * 1024 # Buffer size passed to recv().
@@ -362,8 +422,6 @@ class _SelectorTransport(transports.Transport):
self._buffer = self._buffer_factory()
self._conn_lost = 0 # Set when call to connection_lost scheduled.
self._closing = False # Set when close() called.
- self._protocol_paused = False
- self.set_write_buffer_limits()
if self._server is not None:
self._server.attach(self)
@@ -410,40 +468,6 @@ class _SelectorTransport(transports.Transport):
server.detach(self)
self._server = None
- def _maybe_pause_protocol(self):
- size = self.get_write_buffer_size()
- if size <= self._high_water:
- return
- if not self._protocol_paused:
- self._protocol_paused = True
- try:
- self._protocol.pause_writing()
- except Exception:
- logger.exception('pause_writing() failed')
-
- def _maybe_resume_protocol(self):
- if (self._protocol_paused and
- self.get_write_buffer_size() <= self._low_water):
- self._protocol_paused = False
- try:
- self._protocol.resume_writing()
- except Exception:
- logger.exception('resume_writing() failed')
-
- def set_write_buffer_limits(self, high=None, low=None):
- if high is None:
- if low is None:
- high = 64*1024
- else:
- high = 4*low
- if low is None:
- low = high // 4
- if not high >= low >= 0:
- raise ValueError('high (%r) must be >= low (%r) must be >= 0' %
- (high, low))
- self._high_water = high
- self._low_water = low
-
def get_write_buffer_size(self):
return len(self._buffer)