[CalendarServer-changes] [9059] CalendarServer/branches/users/glyph/ipv6-client/twext/internet

source_changes at macosforge.org source_changes at macosforge.org
Fri Apr 13 11:44:08 PDT 2012


Revision: 9059
          http://trac.macosforge.org/projects/calendarserver/changeset/9059
Author:   glyph at apple.com
Date:     2012-04-13 11:44:08 -0700 (Fri, 13 Apr 2012)
Log Message:
-----------
connection failed, disconnect while connecting

Modified Paths:
--------------
    CalendarServer/branches/users/glyph/ipv6-client/twext/internet/adaptendpoint.py
    CalendarServer/branches/users/glyph/ipv6-client/twext/internet/test/test_adaptendpoint.py

Modified: CalendarServer/branches/users/glyph/ipv6-client/twext/internet/adaptendpoint.py
===================================================================
--- CalendarServer/branches/users/glyph/ipv6-client/twext/internet/adaptendpoint.py	2012-04-13 18:44:01 UTC (rev 9058)
+++ CalendarServer/branches/users/glyph/ipv6-client/twext/internet/adaptendpoint.py	2012-04-13 18:44:08 UTC (rev 9059)
@@ -26,6 +26,7 @@
 
 from twisted.internet.protocol import Factory
 from twisted.python import log
+from twisted.python.util import FancyEqMixin
 
 
 
@@ -55,13 +56,15 @@
 
 
 
-class LegacyConnector(object):
+class LegacyConnector(FancyEqMixin, object):
     """
     Legacy IConnector interface implementation for stuff that uses endpoints.
     """
     implements(IConnector)
 
+    compareAttributes = tuple(["wrapper"])
 
+
     def __init__(self, wrapper):
         self.wrapper = wrapper
 
@@ -79,11 +82,10 @@
 
     def stopConnecting(self):
         self.wrapper.stopConnectionAttempt()
-        self.wrapper.endpoint.connect(self.wrapper)
 
 
     def disconnect(self):
-        pass
+        self.wrapper.disconnect()
 
 
 
@@ -94,12 +96,23 @@
         self.legacyFactory = legacyFactory
         self.endpoint = endpoint
         self._connectedProtocol = None
+        self._outstandingAttempt = None
 
 
     def buildProtocol(self, addr):
         return _WrappedProtocol(self.legacyFactory.buildProtocol(addr), self)
 
 
+    def startAttempt(self):
+        self.callStartedConnecting()
+        d = self._outstandingAttempt = self.endpoint.connect(self)
+        @d.addBoth
+        def attemptDone(result):
+            self._outstandingAttempt = None
+            return result
+        d.addErrback(self.callClientConnectionFailed)
+
+
     def callStartedConnecting(self):
         self.legacyFactory.startedConnecting(LegacyConnector(self))
 
@@ -108,24 +121,24 @@
         self.legacyFactory.clientConnectionLost(LegacyConnector(self), reason)
 
 
-    def callClientConnectionFailed(self):
-        self.legacyFactory.clientConnectionFailed()
+    def callClientConnectionFailed(self, reason):
+        self.legacyFactory.clientConnectionFailed(LegacyConnector(self), reason)
 
 
     def disconnect(self):
         if self._connectedProtocol is not None:
-            self._connectedProtocol.transport.abortConnection()
-        else:
-            pass
+            self._connectedProtocol.transport.loseConnection()
+        elif self._outstandingAttempt is not None:
+            self._outstandingAttempt.cancel()
 
-# from twisted.internet.interfaces import IStreamClientEndpoint
 
+
 def connect(endpoint, clientFactory):
     """
     Connect a L{twisted.internet.protocol.ClientFactory} using the given
     L{twisted.internet.interfaces.IStreamClientEndpoint}.
     """
     wrap = LegacyClientFactoryWrapper(clientFactory, endpoint)
-    endpoint.connect(wrap)
+    wrap.startAttempt()
     return LegacyConnector(wrap)
 

Modified: CalendarServer/branches/users/glyph/ipv6-client/twext/internet/test/test_adaptendpoint.py
===================================================================
--- CalendarServer/branches/users/glyph/ipv6-client/twext/internet/test/test_adaptendpoint.py	2012-04-13 18:44:01 UTC (rev 9058)
+++ CalendarServer/branches/users/glyph/ipv6-client/twext/internet/test/test_adaptendpoint.py	2012-04-13 18:44:08 UTC (rev 9059)
@@ -21,7 +21,7 @@
 from zope.interface.verify import verifyObject
 
 from twext.internet.adaptendpoint import connect
-from twisted.internet.defer import Deferred
+from twisted.internet.defer import Deferred, CancelledError
 from twisted.python.failure import Failure
 
 from twisted.internet.protocol import ClientFactory, Protocol
@@ -68,21 +68,26 @@
         self.fails = []
         self.lost = []
 
+
     def startedConnecting(self, ctr):
         self.starts.append(ctr)
 
+
     def clientConnectionFailed(self, ctr, reason):
         self.fails.append(names(connector=ctr, reason=reason))
 
+
     def clientConnectionLost(self, ctr, reason):
         self.lost.append(names(connector=ctr, reason=reason))
 
+
     def buildProtocol(self, addr):
         b =  RecordingProtocol()
         self.built.append(names(protocol=b, addr=addr))
         return b
 
 
+
 class RecordingEndpoint(object):
 
     def __init__(self):
@@ -111,6 +116,7 @@
         ctr = connect(e, rcf)
         self.assertIdentical(ctr.getDestination(), e)
         verifyObject(IConnector, ctr)
+        self.assertEqual(rcf.starts, [ctr])
         self.assertEqual(len(e.attempts), 1)
         self.assertEqual(len(rcf.built), 0)
         proto = e.attempts[0].factory.buildProtocol(object)
@@ -126,7 +132,7 @@
     def test_connectionLost(self):
         """
         When the connection is lost, both the protocol and the factory will be
-        notified via connectionLost and clientConnectionLost.
+        notified via C{connectionLost} and C{clientConnectionLost}.
         """
         rcf = RecordingClientFactory()
         e = RecordingEndpoint()
@@ -141,3 +147,32 @@
         self.assertIdentical(rcf.lost[0].reason, why)
 
 
+    def test_connectionFailed(self):
+        """
+        When the L{Deferred} from the endpoint fails, the L{ClientFactory} gets
+        notified via C{clientConnectionFailed}.
+        """
+        rcf = RecordingClientFactory()
+        e = RecordingEndpoint()
+        connect(e, rcf)
+        why = Failure(RuntimeError())
+        e.attempts[0].deferred.errback(why)
+        self.assertEquals(len(rcf.fails), 1)
+        self.assertIdentical(rcf.fails[0].reason, why)
+
+
+    def test_disconnectWhileConnecting(self):
+        """
+        If the L{IConnector} is told to C{disconnect} before an in-progress
+        L{Deferred} from C{connect} has fired, it will cancel that L{Deferred}.
+        """
+        rcf = RecordingClientFactory()
+        e = RecordingEndpoint()
+        connect(e, rcf)
+        ctr = rcf.starts[0]
+        ctr.disconnect()
+        self.assertEqual(len(rcf.fails), 1)
+        self.assertTrue(rcf.fails[0].reason.check(CancelledError))
+
+
+
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20120413/3fa1c311/attachment.html>


More information about the calendarserver-changes mailing list