[Zodb-checkins] CVS: ZODB3/ZEO - smac.py:1.19

Jeremy Hylton jeremy@zope.com
Thu, 22 Aug 2002 14:29:14 -0400


Update of /cvs-repository/ZODB3/ZEO
In directory cvs.zope.org:/tmp/cvs-serv22017

Modified Files:
	smac.py 
Log Message:
Cleanup implementation of string accumulation in handle_write().

Boost the accumulator limit to 60000.
Use "".join() to accumulate multiple strings, since it is not unusual
to have more than 2 strings to join together.

Add comment explaining why we do this stuff.


=== ZODB3/ZEO/smac.py 1.18 => 1.19 ===
--- ZODB3/ZEO/smac.py:1.18	Tue Jul  2 03:29:05 2002
+++ ZODB3/ZEO/smac.py	Thu Aug 22 14:29:13 2002
@@ -137,21 +137,40 @@
     def handle_write(self):
         output = self.__output
         while output:
-            v = output[0]
-            while len(output)>1 and len(v)<16384:
-                del output[0]
-                v += output[0]
+            # Accumulate output into a single string so that we avoid
+            # multiple send() calls, but avoid accumulating too much
+            # data.  If we send a very small string and have more data
+            # to send, we will likely incur delays caused by the
+            # unfortunate interaction between the Nagle algorithm and
+            # delayed acks.  If we send a very large string, only a
+            # portion of it will actually be delivered at a time.
+
+            # We chose 60000 as the socket limit by looking at the
+            # largest strings that we could pass to send() without
+            # blocking.
+
+            l = 0
+            for i in range(len(output)):
+                l += len(output[i])
+                if l > 60000:
+                    break
+
+            i += 1
+            # It is very unlikely that i will be 1.
+            v = "".join(output[:i])
+            del output[:i]
+
             try:
-                n=self.send(v)
+                n = self.send(v)
             except socket.error, err:
                 if err[0] in expected_socket_write_errors:
                     break # we couldn't write anything
                 raise
             if n < len(v):
-                output[0] = v[n:]
+                # XXX It's unfortunate that we end up making many
+                # slices of a large string.
+                output.insert(0, v[n:])
                 break # we can't write any more
-            else:
-                del output[0]
 
     def handle_close(self):
         self.close()