commit 90510d7bf565f0cc9876665aa6e85b55c8e5a3c1 Author: David Fifield david@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")
tor-commits@lists.torproject.org