[CalendarServer-changes] [9032] CalendarServer/trunk

source_changes at macosforge.org source_changes at macosforge.org
Wed Apr 11 15:15:31 PDT 2012


Revision: 9032
          http://trac.macosforge.org/projects/calendarserver/changeset/9032
Author:   sagen at apple.com
Date:     2012-04-11 15:15:31 -0700 (Wed, 11 Apr 2012)
Log Message:
-----------
Loadtest sim now unsubscribes from pubsub at shutdown.

Modified Paths:
--------------
    CalendarServer/trunk/calendarserver/tools/notifications.py
    CalendarServer/trunk/contrib/performance/loadtest/ical.py
    CalendarServer/trunk/contrib/performance/loadtest/population.py
    CalendarServer/trunk/contrib/performance/loadtest/sim.py
    CalendarServer/trunk/contrib/performance/loadtest/test_sim.py

Modified: CalendarServer/trunk/calendarserver/tools/notifications.py
===================================================================
--- CalendarServer/trunk/calendarserver/tools/notifications.py	2012-04-11 22:15:14 UTC (rev 9031)
+++ CalendarServer/trunk/calendarserver/tools/notifications.py	2012-04-11 22:15:31 UTC (rev 9032)
@@ -156,7 +156,7 @@
 
     pubsubNS = 'http://jabber.org/protocol/pubsub'
 
-    def __init__(self, jid, password, service, nodes, verbose):
+    def __init__(self, jid, password, service, nodes, verbose, sigint=True):
         resource = "pushmonitor.%s" % (uuid.uuid4().hex,)
         self.jid = "%s/%s" % (jid, resource)
         self.service = service
@@ -184,15 +184,20 @@
         self.addBootstrap(IQAuthInitializer.AUTH_FAILED_EVENT,
             self.authFailed)
 
-        signal.signal(signal.SIGINT, self.sigint_handler)
+        if sigint:
+            signal.signal(signal.SIGINT, self.sigint_handler)
 
     @inlineCallbacks
     def sigint_handler(self, num, frame):
         print " Shutting down..."
+        yield self.unsubscribeAll()
+        reactor.stop()
+
+    @inlineCallbacks
+    def unsubscribeAll(self):
         if self.xmlStream is not None:
             for node, (url, name, kind) in self.nodes.iteritems():
                 yield self.unsubscribe(node, name, kind)
-        reactor.stop()
 
     def connected(self, xmlStream):
         self.xmlStream = xmlStream

Modified: CalendarServer/trunk/contrib/performance/loadtest/ical.py
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/ical.py	2012-04-11 22:15:14 UTC (rev 9031)
+++ CalendarServer/trunk/contrib/performance/loadtest/ical.py	2012-04-11 22:15:31 UTC (rev 9032)
@@ -72,7 +72,12 @@
         self.response = response
 
 
+class MissingCalendarHome(Exception):
+    """
+    Raised when the calendar home for a user is 404
+    """
 
+
 class XMPPPush(object, FancyEqMixin):
     """
     This represents an XMPP PubSub location where push notifications for
@@ -293,6 +298,9 @@
         # values.
         self.xmpp = {}
 
+        # Keep track of push factories so we can unsubscribe at shutdown
+        self._pushFactories = []
+
         # Allow events to go out into the world.
         self.catalog = {
             "eventChanged": Periodical(),
@@ -905,11 +913,19 @@
         factory = _PubSubClientFactory(
             self, "%s@%s" % (self.record.uid, host),
             self.record.password, service,
-            {params.pushkey: (home, home, "Calendar home")}, False)
+            {params.pushkey: (home, home, "Calendar home")}, False,
+            sigint=False)
+        self._pushFactories.append(factory)
         self.reactor.connectTCP(host, port, factory)
 
 
     @inlineCallbacks
+    def _unsubscribePubSub(self):
+        for factory in self._pushFactories:
+            yield factory.unsubscribeAll()
+
+
+    @inlineCallbacks
     def run(self):
         """
         Emulate a CalDAV client.
@@ -919,10 +935,12 @@
             principal = yield self.startup()
             hrefs = principal.getHrefProperties()
             calendarHome = hrefs[caldavxml.calendar_home_set].toString()
+            if calendarHome is None:
+                raise MissingCalendarHome
             yield self._checkCalendarsForEvents(calendarHome, firstTime=True)
             returnValue(calendarHome)
         calendarHome = yield self._newOperation("startup: %s" % (self._client_type,), startup())
-        
+
         self.started = True
 
         # Start monitoring PubSub notifications, if possible.
@@ -938,6 +956,12 @@
             yield self._calendarCheckLoop(calendarHome)
 
 
+    def stop(self):
+        """
+        Called before connections are closed, giving a chance to clean up
+        """
+        return self._unsubscribePubSub()
+
     def _makeSelfAttendee(self):
         attendee = Property(
             name=u'ATTENDEE',

Modified: CalendarServer/trunk/contrib/performance/loadtest/population.py
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/population.py	2012-04-11 22:15:14 UTC (rev 9031)
+++ CalendarServer/trunk/contrib/performance/loadtest/population.py	2012-04-11 22:15:31 UTC (rev 9032)
@@ -27,6 +27,7 @@
 from itertools import izip
 from datetime import datetime
 
+from twisted.internet.defer import DeferredList
 from twisted.python.failure import Failure
 from twisted.python.filepath import FilePath
 from twisted.python.util import FancyEqMixin
@@ -163,6 +164,7 @@
         self._stopped = False
         self.workerIndex = workerIndex
         self.workerCount = workerCount
+        self.clients = []
 
         TimezoneCache.create()
 
@@ -196,7 +198,13 @@
         disregarded (as some are expected, as the simulation will always stop
         while some requests are in flight).
         """
+
+        # Give all the clients a chance to stop (including unsubscribe from push)
+        deferreds = []
+        for client in self.clients:
+            deferreds.append(client.stop())
         self._stopped = True
+        return DeferredList(deferreds)
 
 
     def add(self, numClients, clientsPerUser):
@@ -216,6 +224,7 @@
                 reactor = loggedReactor(self.reactor)
                 client = clientType.new(
                     reactor, self.server, self.getUserRecord(number), auth)
+                self.clients.append(client)
                 d = client.run()
                 d.addErrback(self._clientFailure, reactor)
     

Modified: CalendarServer/trunk/contrib/performance/loadtest/sim.py
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/sim.py	2012-04-11 22:15:14 UTC (rev 9031)
+++ CalendarServer/trunk/contrib/performance/loadtest/sim.py	2012-04-11 22:15:31 UTC (rev 9032)
@@ -34,6 +34,7 @@
 
 from twisted.internet.defer import Deferred
 from twisted.internet.defer import gatherResults
+from twisted.internet.defer import inlineCallbacks
 from twisted.internet.protocol import ProcessProtocol
 
 from contrib.performance.loadtest.ical import OS_X_10_6
@@ -386,7 +387,7 @@
 
     def shutdown(self):
         if self.ms.running:
-            self.ms.stopService()
+            return self.ms.stopService()
 
 
 def attachService(reactor, loadsim, service):
@@ -446,9 +447,10 @@
         arrivalPolicy.run(self.clientsim)
 
 
+    @inlineCallbacks
     def stopService(self):
-        super(SimulatorService, self).stopService()
-        return self.clientsim.stop()
+        yield super(SimulatorService, self).stopService()
+        yield self.clientsim.stop()
 
 
 

Modified: CalendarServer/trunk/contrib/performance/loadtest/test_sim.py
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/test_sim.py	2012-04-11 22:15:14 UTC (rev 9031)
+++ CalendarServer/trunk/contrib/performance/loadtest/test_sim.py	2012-04-11 22:15:31 UTC (rev 9032)
@@ -21,7 +21,7 @@
 from twisted.python.log import msg
 from twisted.python.usage import UsageError
 from twisted.python.filepath import FilePath
-from twisted.internet.defer import Deferred
+from twisted.internet.defer import Deferred, succeed
 from twisted.trial.unittest import TestCase
 
 from twistedcaldav.directory.directory import DirectoryRecord
@@ -151,6 +151,9 @@
 
             def run(self):
                 return self._runResult
+
+            def stop(self):
+                return succeed(None)
                 
         class BrokenProfile(object):
             def __init__(self, reactor, simulator, client, userNumber, runResult):
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20120411/89c17e7e/attachment.html>


More information about the calendarserver-changes mailing list