From 06b0cdbfaa7f016ebf5cf5aa8e069e038b013f09 Mon Sep 17 00:00:00 2001 From: "P. Christeas" Date: Tue, 18 Jan 2011 14:59:03 +0200 Subject: [PATCH 1/4] net-rpc: Send all data in one TCP packet This optimises the TCP layer significantly, avoids ACK delays. Inspired by: Julien Thewys bzr revid: p_christ@hol.gr-20110118125903-5hrg89kpi1vuadv9 --- bin/tiny_socket.py | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/bin/tiny_socket.py b/bin/tiny_socket.py index 6a0d9371ef5..44f7db04f01 100644 --- a/bin/tiny_socket.py +++ b/bin/tiny_socket.py @@ -61,15 +61,7 @@ class mysocket: def mysend(self, msg, exception=False, traceback=None): msg = cPickle.dumps([msg,traceback]) - size = len(msg) - self.sock.send('%8d' % size) - self.sock.send(exception and "1" or "0") - totalsent = 0 - while totalsent < size: - sent = self.sock.send(msg[totalsent:]) - if sent == 0: - raise RuntimeError, "socket connection broken" - totalsent = totalsent + sent + self.sock.sendall('%8d%s%s' % (len(msg), exception and "1" or "0", msg)) def myreceive(self): buf='' From 5168d0bd09fb1e498ac4902957fd722042db0e9c Mon Sep 17 00:00:00 2001 From: "P. Christeas" Date: Tue, 18 Jan 2011 14:59:07 +0200 Subject: [PATCH 2/4] websrv_lib: defer one socket.flush(), keep packets minimum. bzr revid: p_christ@hol.gr-20110118125907-t7dz40a40pj6k8gs --- bin/service/websrv_lib.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bin/service/websrv_lib.py b/bin/service/websrv_lib.py index 859845de8f8..a64a1371079 100644 --- a/bin/service/websrv_lib.py +++ b/bin/service/websrv_lib.py @@ -182,12 +182,13 @@ class FixSendError: self.send_header('Connection', 'close') self.send_header('Content-Length', len(content) or 0) self.end_headers() - if hasattr(self, '_flush'): - self._flush() if self.command != 'HEAD' and code >= 200 and code not in (204, 304): self.wfile.write(content) + if hasattr(self, '_flush'): + self._flush() + class HttpOptions: _HTTP_OPTIONS = {'Allow': ['OPTIONS' ] } From 6e2fee84f8524a2bc9795b482e6add2ac1f5aee9 Mon Sep 17 00:00:00 2001 From: "P. Christeas" Date: Tue, 18 Jan 2011 14:59:59 +0200 Subject: [PATCH 3/4] http_server: enable write-buffering for TCP sockets When sending http data, we need to minimize the number of TCP packets. By enabling write-buffering, we can achieve that. However, we need to make sure that buffers will properly be flushed, not linger. Conflicts: bin/service/http_server.py bzr revid: p_christ@hol.gr-20110118125959-vk0gzx30bwykn18s --- bin/service/http_server.py | 2 ++ bin/service/websrv_lib.py | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/bin/service/http_server.py b/bin/service/http_server.py index f40e1df5ba8..e2ae90918b7 100644 --- a/bin/service/http_server.py +++ b/bin/service/http_server.py @@ -123,10 +123,12 @@ class HttpLogHandler: class MultiHandler2(HttpLogHandler, MultiHTTPHandler): _logger = logging.getLogger('http') + wbufsize = 32768 class SecureMultiHandler2(HttpLogHandler, SecureMultiHTTPHandler): _logger = logging.getLogger('https') + wbufsize = 32768 def getcert_fnames(self): tc = tools.config diff --git a/bin/service/websrv_lib.py b/bin/service/websrv_lib.py index a64a1371079..03b0032542b 100644 --- a/bin/service/websrv_lib.py +++ b/bin/service/websrv_lib.py @@ -481,6 +481,10 @@ class SecureMultiHTTPHandler(MultiHTTPHandler): except Exception: pass + def handle_one_request(self): + MultiHTTPHandler.handle_one_request(self) + self.wfile.flush() + import threading class ConnThreadingMixIn: """Mix-in class to handle each _connection_ in a new thread. From e82fca056db2c62a7b1bde42966cc0c6b66770b8 Mon Sep 17 00:00:00 2001 From: "P. Christeas" Date: Tue, 18 Jan 2011 15:00:05 +0200 Subject: [PATCH 4/4] websrv_lib: flush at plain http, too Since the write-buffering was enabled, it is now needed to flush. Fixes static http, at least. bzr revid: p_christ@hol.gr-20110118130005-tk5rz84po3q7qofu --- bin/service/websrv_lib.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bin/service/websrv_lib.py b/bin/service/websrv_lib.py index 03b0032542b..dff77fa6a87 100644 --- a/bin/service/websrv_lib.py +++ b/bin/service/websrv_lib.py @@ -396,6 +396,7 @@ class MultiHTTPHandler(FixSendError, HttpOptions, BaseHTTPRequestHandler): return if not self.parse_rawline(): self.log_message("Could not parse rawline.") + self.wfile.flush() return # self.parse_request(): # Do NOT parse here. the first line should be the only @@ -404,6 +405,7 @@ class MultiHTTPHandler(FixSendError, HttpOptions, BaseHTTPRequestHandler): if not self.parse_request(): return self.do_OPTIONS() + self.wfile.flush() return for vdir in self.server.vdirs: @@ -430,9 +432,11 @@ class MultiHTTPHandler(FixSendError, HttpOptions, BaseHTTPRequestHandler): "client closed connection", self.rlpath.rstrip()) else: raise + self.wfile.flush() return # if no match: self.send_error(404, "Path not found: %s" % self.path) + self.wfile.flush() return def _get_ignore_body(self,fore): @@ -481,10 +485,6 @@ class SecureMultiHTTPHandler(MultiHTTPHandler): except Exception: pass - def handle_one_request(self): - MultiHTTPHandler.handle_one_request(self) - self.wfile.flush() - import threading class ConnThreadingMixIn: """Mix-in class to handle each _connection_ in a new thread.