diff options
author | Michael Merickel <michael@merickel.org> | 2020-05-20 15:59:18 -0500 |
---|---|---|
committer | Michael Merickel <michael@merickel.org> | 2020-05-20 15:59:18 -0500 |
commit | 561735bc8be151dd1f04c459d5c6ebfa451bc951 (patch) | |
tree | aabfdbd0f40d3b5a06962cbbf8ab23d916980634 /src/waitress/channel.py | |
parent | d9384f456a881f7d6362595f3a6f48021e14eca6 (diff) | |
download | waitress-561735bc8be151dd1f04c459d5c6ebfa451bc951.tar.gz |
stabilize buffer behavior with multiple requests on the same connection
previous to this change, a buffer may be reused across requests, and
would cause data to be written to disk even if each individual request
was not returning much data
fixes #265
Diffstat (limited to 'src/waitress/channel.py')
-rw-r--r-- | src/waitress/channel.py | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/src/waitress/channel.py b/src/waitress/channel.py index a8bc76f..bc9a2bb 100644 --- a/src/waitress/channel.py +++ b/src/waitress/channel.py @@ -174,9 +174,10 @@ class HTTPChannel(wasyncore.dispatcher, object): # there's no current task, so we don't need to try to # lock the outbuf to append to it. outbuf_payload = b"HTTP/1.1 100 Continue\r\n\r\n" + num_bytes = len(outbuf_payload) self.outbufs[-1].append(outbuf_payload) - self.current_outbuf_count += len(outbuf_payload) - self.total_outbufs_len += len(outbuf_payload) + self.current_outbuf_count += num_bytes + self.total_outbufs_len += num_bytes self.sent_continue = True self._flush_some() request.completed = False @@ -311,7 +312,7 @@ class HTTPChannel(wasyncore.dispatcher, object): self.outbufs.append(nextbuf) self.current_outbuf_count = 0 else: - if self.current_outbuf_count > self.adj.outbuf_high_watermark: + if self.current_outbuf_count >= self.adj.outbuf_high_watermark: # rotate to a new buffer if the current buffer has hit # the watermark to avoid it growing unbounded nextbuf = OverflowableBuffer(self.adj.outbuf_overflow) @@ -399,6 +400,15 @@ class HTTPChannel(wasyncore.dispatcher, object): # at the end to account for consecutive service() calls if len(self.requests) > 1: self._flush_outbufs_below_high_watermark() + + # this is a little hacky but basically it's forcing the + # next request to create a new outbuf to avoid sharing + # outbufs across requests which can cause outbufs to + # not be deallocated regularly when a connection is open + # for a long time + if self.current_outbuf_count > 0: + self.current_outbuf_count = self.adj.outbuf_high_watermark + request = self.requests.pop(0) request.close() |