[CalendarServer-changes] [4800] CalendarServer/branches/users/cdaboo/deployment-partition-4722
source_changes at macosforge.org
source_changes at macosforge.org
Mon Nov 23 12:46:38 PST 2009
Revision: 4800
http://trac.macosforge.org/projects/calendarserver/changeset/4800
Author: cdaboo at apple.com
Date: 2009-11-23 12:46:35 -0800 (Mon, 23 Nov 2009)
Log Message:
-----------
Fixing up client pool error handling.
Modified Paths:
--------------
CalendarServer/branches/users/cdaboo/deployment-partition-4722/twistedcaldav/client/pool.py
Added Paths:
-----------
CalendarServer/branches/users/cdaboo/deployment-partition-4722/lib-patches/Twisted/twisted.web2.client.http.patch
Added: CalendarServer/branches/users/cdaboo/deployment-partition-4722/lib-patches/Twisted/twisted.web2.client.http.patch
===================================================================
--- CalendarServer/branches/users/cdaboo/deployment-partition-4722/lib-patches/Twisted/twisted.web2.client.http.patch (rev 0)
+++ CalendarServer/branches/users/cdaboo/deployment-partition-4722/lib-patches/Twisted/twisted.web2.client.http.patch 2009-11-23 20:46:35 UTC (rev 4800)
@@ -0,0 +1,14 @@
+Index: twisted/web2/client/http.py
+===================================================================
+--- twisted/web2/client/http.py (revision 19773)
++++ twisted/web2/client/http.py (working copy)
+@@ -134,8 +134,7 @@
+ self.responseDefer.errback(ProtocolError(text))
+
+ def connectionLost(self, reason):
+- ### FIXME!
+- pass
++ self._error(reason)
+
+ def gotInitialLine(self, initialLine):
+ parts = initialLine.split(' ', 2)
Modified: CalendarServer/branches/users/cdaboo/deployment-partition-4722/twistedcaldav/client/pool.py
===================================================================
--- CalendarServer/branches/users/cdaboo/deployment-partition-4722/twistedcaldav/client/pool.py 2009-11-23 19:21:36 UTC (rev 4799)
+++ CalendarServer/branches/users/cdaboo/deployment-partition-4722/twistedcaldav/client/pool.py 2009-11-23 20:46:35 UTC (rev 4800)
@@ -21,8 +21,8 @@
]
from twisted.internet.address import IPv4Address
-from twisted.internet.defer import Deferred
-from twisted.internet.protocol import ReconnectingClientFactory
+from twisted.internet.defer import Deferred, inlineCallbacks, returnValue
+from twisted.internet.protocol import ClientFactory
from twisted.internet.ssl import DefaultOpenSSLContextFactory
from twisted.web2 import responsecode
from twisted.web2.client.http import HTTPClientProtocol
@@ -31,17 +31,17 @@
import OpenSSL
import urlparse
-class ReverseProxyClientFactory(ReconnectingClientFactory, LoggingMixIn):
+class ReverseProxyClientFactory(ClientFactory, LoggingMixIn):
"""
- A client factory for HTTPClient that notifies a pool of it's state.
+ A client factory for HTTPClient that notifies a pool of it's state. It the connection
+ fails in the middle of a request it will retry the request.
- @ivar connectionPool: A managing connection pool that we notify of events.
@ivar protocol: The current instance of our protocol that we pass
to our connectionPool.
+ @ivar connectionPool: A managing connection pool that we notify of events.
"""
protocol = HTTPClientProtocol
connectionPool = None
- maxRetries = 2
def __init__(self, reactor):
self.reactor = reactor
@@ -98,6 +98,7 @@
progress.
"""
clientFactory = ReverseProxyClientFactory
+ maxRetries = 2
def __init__(self, scheme, serverAddress, maxClients=5, reactor=None):
"""
@@ -200,6 +201,7 @@
d.addCallback(_freeClientAfterRequest)
return d
+ @inlineCallbacks
def submitRequest(self, request, *args, **kwargs):
"""
Select an available client and perform the given request on it.
@@ -214,6 +216,33 @@
@return: A L{Deferred} that fires with the result of the given command.
"""
+ # Try this maxRetries times
+ for ctr in xrange(self.maxRetries + 1):
+ try:
+ response = yield self._submitRequest(request, args, kwargs)
+ except Exception, e:
+ self.log_error("ReverseProxy connection error (attempt: %d) - retrying: %s" % (ctr+1, e,))
+ continue
+ else:
+ returnValue(response)
+ else:
+ self.log_error("ReverseProxy connection error - exhausted retry attempts: %s" % (e,))
+ raise HTTPError(StatusResponse(responsecode.BAD_GATEWAY, "Could not connect to reverse proxy host."))
+
+ def _submitRequest(self, request, *args, **kwargs):
+ """
+ Select an available client and perform the given request on it.
+
+ @param command: A C{str} representing an attribute of
+ L{MemCacheProtocol}.
+ @parma args: Any positional arguments that should be passed to
+ C{command}.
+ @param kwargs: Any keyword arguments that should be passed to
+ C{command}.
+
+ @return: A L{Deferred} that fires with the result of the given command.
+ """
+
client = None
if len(self._freeClients) > 0:
client = self._freeClients.pop()
@@ -227,8 +256,12 @@
self._logClientStats()
else:
+ def _badGateway(f):
+ raise HTTPError(StatusResponse(responsecode.BAD_GATEWAY, "Could not connect to reverse proxy host."))
+
d = self._newClientConnection()
d.addCallback(self._performRequestOnClient, request, *args, **kwargs)
+ d.addErrback(_badGateway)
return d
@@ -255,6 +288,8 @@
self.log_debug("Removed client: %r" % (client,))
self._logClientStats()
+ self._processPending()
+
def clientBusy(self, client):
"""
Notify that the given client is being used to complete a request.
@@ -284,6 +319,12 @@
if self.shutdown_deferred and self._isIdle():
self.shutdown_deferred.callback(None)
+ self.log_debug("Freed client: %r" % (client,))
+ self._logClientStats()
+
+ self._processPending()
+
+ def _processPending(self):
if len(self._pendingRequests) > 0:
d, request, args, kwargs = self._pendingRequests.pop(0)
@@ -291,13 +332,11 @@
request, args, kwargs))
self._logClientStats()
- _ign_d = self.submitRequest(request, *args, **kwargs)
+ _ign_d = self._submitRequest(request, *args, **kwargs)
_ign_d.addCallback(d.callback)
+ _ign_d.addErrback(d.errback)
- self.log_debug("Freed client: %r" % (client,))
- self._logClientStats()
-
def suggestMaxClients(self, maxClients):
"""
Suggest the maximum number of concurrently connected clients.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20091123/b56e15d9/attachment-0001.html>
More information about the calendarserver-changes
mailing list