summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Merickel <michael@merickel.org>2019-04-05 13:19:13 -0500
committerMichael Merickel <michael@merickel.org>2019-04-05 13:36:54 -0500
commit291f8e196ccb4343e2539a55d480b0b5a76d1e87 (patch)
tree7afdd1521fa565392b5011006c17f9595362ef61
parentecf13757fd585dbf7f2f9539663c69e261442c29 (diff)
downloadwaitress-291f8e196ccb4343e2539a55d480b0b5a76d1e87.tar.gz
simplify rotation
-rw-r--r--waitress/channel.py17
-rw-r--r--waitress/tests/test_channel.py23
2 files changed, 20 insertions, 20 deletions
diff --git a/waitress/channel.py b/waitress/channel.py
index 27eb532..6f20742 100644
--- a/waitress/channel.py
+++ b/waitress/channel.py
@@ -222,7 +222,7 @@ class HTTPChannel(wasyncore.dispatcher, object):
while True:
outbuf = self.outbufs[0]
# use outbuf.__len__ rather than len(outbuf) FBO of not getting
- # OverflowError on 32-bit Python
+ # OverflowError on 32-bit Python
outbuflen = outbuf.__len__()
while outbuflen > 0:
chunk = outbuf.get(self.sendbuf_len)
@@ -303,7 +303,7 @@ class HTTPChannel(wasyncore.dispatcher, object):
# the async mainloop might be popping data off outbuf; we can
# block here waiting for it because we're in a task thread
with self.outbuf_lock:
- overflowed = self._flush_outbufs_below_high_watermark()
+ self._flush_outbufs_below_high_watermark()
if not self.connected:
raise ClientDisconnected
if data.__class__ is ReadOnlyFileBasedBuffer:
@@ -313,12 +313,9 @@ class HTTPChannel(wasyncore.dispatcher, object):
self.outbufs.append(nextbuf)
self.current_outbuf_count = 0
else:
- # if we overflowed then start a new buffer to ensure
- # the original eventually gets pruned otherwise it may
- # grow unbounded
- if overflowed or (
- self.current_outbuf_count > self.adj.outbuf_high_watermark
- ):
+ # if we overflowed then start a new buffer to ensure avoid
+ # this buffer growing unbounded
+ if self.current_outbuf_count > self.adj.outbuf_high_watermark:
nextbuf = OverflowableBuffer(self.adj.outbuf_overflow)
self.outbufs.append(nextbuf)
self.current_outbuf_count = 0
@@ -334,16 +331,14 @@ class HTTPChannel(wasyncore.dispatcher, object):
return 0
def _flush_outbufs_below_high_watermark(self):
- overflowed = self.total_outbufs_len > self.adj.outbuf_high_watermark
# check first to avoid locking if possible
- if overflowed:
+ if self.total_outbufs_len > self.adj.outbuf_high_watermark:
with self.outbuf_lock:
while (
self.connected and
self.total_outbufs_len > self.adj.outbuf_high_watermark
):
self.outbuf_lock.wait()
- return overflowed
def service(self):
"""Execute all pending requests """
diff --git a/waitress/tests/test_channel.py b/waitress/tests/test_channel.py
index ff3bba6..35fccf6 100644
--- a/waitress/tests/test_channel.py
+++ b/waitress/tests/test_channel.py
@@ -239,18 +239,27 @@ class TestHTTPChannel(unittest.TestCase):
def test_write_soon_rotates_outbuf_on_overflow(self):
inst, sock, map = self._makeOneWithMap()
inst.adj.outbuf_high_watermark = 3
- inst.outbufs = [DummyBuffer(b'abcd')]
- inst.total_outbufs_len = sum(len(x) for x in inst.outbufs)
+ inst.current_outbuf_count = 4
+ wrote = inst.write_soon(b'xyz')
+ self.assertEqual(wrote, 3)
+ self.assertEqual(len(inst.outbufs), 2)
+ self.assertEqual(inst.outbufs[0].get(), b'')
+ self.assertEqual(inst.outbufs[1].get(), b'xyz')
+
+ def test_write_soon_waits_on_backpressure(self):
+ inst, sock, map = self._makeOneWithMap()
+ inst.adj.outbuf_high_watermark = 3
+ inst.total_outbufs_len = 4
+ inst.current_outbuf_count = 4
class Lock(DummyLock):
def wait(self):
- inst.outbufs[0].prune()
- inst.total_outbufs_len = sum(len(x) for x in inst.outbufs)
+ inst.total_outbufs_len = 0
super(Lock, self).wait()
inst.outbuf_lock = Lock()
wrote = inst.write_soon(b'xyz')
self.assertEqual(wrote, 3)
self.assertEqual(len(inst.outbufs), 2)
- self.assertTrue(inst.outbufs[0].pruned)
+ self.assertEqual(inst.outbufs[0].get(), b'')
self.assertEqual(inst.outbufs[1].get(), b'xyz')
self.assertTrue(inst.outbuf_lock.waited)
@@ -753,10 +762,6 @@ class DummyBuffer(object):
def skip(self, num, x):
self.skipped = num
- def prune(self):
- self.pruned = True
- self.data = b''
-
def __len__(self):
return len(self.data)