[tor-commits] [flashproxy/master] Make facilitator requests block until a reg is available.

dcf at torproject.org dcf at torproject.org
Sun Aug 21 09:40:32 UTC 2011


commit 90510d7bf565f0cc9876665aa6e85b55c8e5a3c1
Author: David Fifield <david at bamsoftware.com>
Date:   Sun Aug 21 01:20:22 2011 -0700

    Make facilitator requests block until a reg is available.
    
    When a GET request happens, no longer return an empty string when there
    are no registrations to hand out. Instead, let the HTTP connection hang
    until there is something, then return. It can happen that the HTTP
    client (a flash proxy) disconnects before receiving its response; if we
    fail to send the reg that has just become available, add it back to the
    front of the queue to be handed out again.
---
 facilitator.py |   36 +++++++++++++++++++++++-------------
 1 files changed, 23 insertions(+), 13 deletions(-)

diff --git a/facilitator.py b/facilitator.py
index b2f8304..4e14408 100755
--- a/facilitator.py
+++ b/facilitator.py
@@ -183,11 +183,23 @@ class RegSet(object):
         finally:
             self.cv.release()
 
+    def add_front(self, reg):
+        self.cv.acquire()
+        try:
+            if reg not in list(self.set):
+                self.set.append(reg)
+                self.cv.notify()
+                return True
+            else:
+                return False
+        finally:
+            self.cv.release()
+
     def fetch(self):
         self.cv.acquire()
         try:
-            if not self.set:
-                return None
+            while not self.set:
+                self.cv.wait()
             return self.set.pop(0)
         finally:
             self.cv.release()
@@ -212,13 +224,16 @@ class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
             return
 
         reg = REGS.fetch()
-        if reg:
+
+        try:
+            self.send_client(reg)
             log(u"proxy %s gets %s, relay %s (now %d)" %
                 (proxy_addr_s, unicode(reg), options.relay_spec, len(REGS)))
-            self.send_client(reg)
-        else:
+        except socket.error:
+            # Something went wrong; likely the proxy disconnected without
+            # receiving a reg. Restore the reg to the front of the queue.
+            REGS.add_front(reg)
             log(u"proxy %s gets none" % proxy_addr_s)
-            self.send_client(None)
 
     def do_POST(self):
         client_addr_s = format_addr(self.client_address)
@@ -286,13 +301,8 @@ class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
             % (format_addr(self.client_address), repr(msg)))
 
     def send_client(self, reg):
-        if reg:
-            client_str = str(reg)
-        else:
-            # Send an empty string rather than a 404 or similar because Flash
-            # Player's URLLoader can't always distinguish a 404 from, say,
-            # "server not found."
-            client_str = ""
+        client_str = str(reg)
+
         self.send_response(200)
         self.send_header("Content-Type", "x-www-form-urlencoded")
         self.send_header("Cache-Control", "no-cache")





More information about the tor-commits mailing list