[Zope-Checkins] CVS: Zope3/lib/python/Zope/Server - HTTPServer.py:1.1.2.13

Shane Hathaway shane@digicool.com
Fri, 30 Nov 2001 10:26:57 -0500


Update of /cvs-repository/Zope3/lib/python/Zope/Server
In directory cvs.zope.org:/tmp/cvs-serv29399/lib/python/Zope/Server

Modified Files:
      Tag: Zope-3x-branch
	HTTPServer.py 
Log Message:
- Added tests of HTTP pipelining and fixed bugs.

- Added tests of publisher retry mechanisms and fixed bugs.

- Rearranged http_task for clarity.

- Moved knowledge of PATH_INFO into BaseRequest only.

- Removed commented code.

- Corrected publisher Retry handling.

All this while riding the VRE.  Gotta love trains! ;-)


=== Zope3/lib/python/Zope/Server/HTTPServer.py 1.1.2.12 => 1.1.2.13 ===
 
 
-# Synchronize access to request queues.
-request_queue_lock = allocate_lock()
+# Synchronize access to the "running_tasks" attribute.
+running_lock = allocate_lock()
 
 
 
@@ -423,17 +423,19 @@
     proto_request = None      # An http_request_data instance
     ready_requests = None     # A list
     last_activity = 0         # Time of last activity
-    running_task = 0          # boolean
+    running_tasks = 0         # boolean
 
     next_channel_cleanup = 0  # A class variable
 
+    #
+    # ASYNCHRONOUS METHODS (incl. __init__)
+    #
 
     def __init__(self, server, conn, addr, adj=None):
         channel_type.__init__(self, server, conn, addr, adj)
         self.last_activity = t = self.creation_time
         self.check_maintenance(t)
 
-
     def add_channel(self, map=None):
         """
         This hook keeps track of opened HTTP channels.
@@ -451,7 +453,6 @@
         if ac.has_key(fd):
             del ac[fd]
 
-
     def check_maintenance(self, now):
         if now < http_channel.next_channel_cleanup:
             return
@@ -471,11 +472,10 @@
         now = time.time()
         cutoff = now - self.adj.channel_timeout
         for channel in self.active_channels.values():
-            if (channel is not self and not channel.running_task and
+            if (channel is not self and not channel.running_tasks and
                 channel.last_activity < cutoff):
                 channel.close()
 
-
     def received(self, data):
         """
         Receives input asynchronously and launches or queues requests.
@@ -497,61 +497,30 @@
                 break
             data = data[n:]
 
-
     def queue_request(self, req):
         """
         Queues requests to be processed in sequence by tasks.
         """
-        rr = self.ready_requests
-        do_now = 1
-        if rr is None:
-            # First request--no need to lock.
-            self.ready_requests = []
-        else:
-            request_queue_lock.acquire()
-            try:
-                if rr:
-                    # The request will be executed when the current
-                    # task is finished.
-                    rr.append(req)
-                    do_now = 0
-                # else no task is running.
-            finally:
-                request_queue_lock.release()
+        do_now = 0
+        running_lock.acquire()
+        try:
+            if self.running_tasks:
+                # Wait for the current tasks to finish.
+                rr = self.ready_requests
+                if rr is None:
+                    rr = []
+                    self.ready_requests = rr
+                rr.append(req)
+            else:
+                # Do it now.
+                self.running_tasks = 1
+                do_now = 1
+        finally:
+            running_lock.release()
         if do_now:
             self.set_sync()
             self.create_task(req)
 
-
-    def create_task(self, req):
-        task = self.task_class(self, req)
-        self.running_task = 1
-        self.server.addTask(task)
-
-
-    def end_task(self, close):
-        self.running_task = 0
-        if close:
-            self.close_when_done()
-        else:
-            self.last_activity = time.time()
-            new_task = 0
-            req = None
-            request_queue_lock.acquire()
-            try:
-                rr = self.ready_requests
-                if rr:
-                    req = rr.pop(0)
-                    new_task = 1
-            finally:
-                request_queue_lock.release()
-            if new_task:
-                # Respond to the next request.
-                self.create_task(req)
-            else:
-                # Wait for another request on this connection.
-                self.set_async()
-
     def handle_error(self):
         # Program error
         t, v = sys.exc_info()[:2]
@@ -565,6 +534,40 @@
         else:
             # Ignore socket errors.
             self.close()
+
+    #
+    # SYNCHRONOUS METHODS
+    #
+
+    def end_task(self, close):
+        # Synchronous.
+        if close:
+            self.close_when_done()
+            return
+        new_req = None
+        running_lock.acquire()
+        try:
+            rr = self.ready_requests
+            if rr:
+                new_req = rr.pop(0)
+            else:
+                self.running_tasks = 0
+        finally:
+            running_lock.release()
+        if new_req:
+            # Respond to the next request.
+            self.create_task(new_req)
+        else:
+            # Wait for another request on this connection.
+            self.set_async()
+
+    #
+    # BOTH MODES
+    #
+
+    def create_task(self, req):
+        task = self.task_class(self, req)
+        self.server.addTask(task)