[CalendarServer-changes] [9507] CalendarServer/trunk/twistedcaldav/directory/directory.py

source_changes at macosforge.org source_changes at macosforge.org
Mon Jul 30 10:23:16 PDT 2012


Revision: 9507
          http://trac.macosforge.org/projects/calendarserver/changeset/9507
Author:   sagen at apple.com
Date:     2012-07-30 10:23:16 -0700 (Mon, 30 Jul 2012)
Log Message:
-----------
Perform a group cacher update when that sidecar receives SIGHUP.

Modified Paths:
--------------
    CalendarServer/trunk/twistedcaldav/directory/directory.py

Modified: CalendarServer/trunk/twistedcaldav/directory/directory.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/directory.py	2012-07-30 17:22:26 UTC (rev 9506)
+++ CalendarServer/trunk/twistedcaldav/directory/directory.py	2012-07-30 17:23:16 UTC (rev 9507)
@@ -30,6 +30,7 @@
 
 import datetime
 import os
+import signal
 import sys
 import types
 import pwd, grp
@@ -851,36 +852,73 @@
         if reactor is None:
             from twisted.internet import reactor
         self.reactor = reactor
+
         self.updateSeconds = updateSeconds
         self.nextUpdate = None
+        self.updateInProgress = False
+        self.updateAwaiting = False
+
         if updateMethod:
             self.updateMethod = updateMethod
         else:
             self.updateMethod = self.updater.updateCache
 
     def startService(self):
+        self.previousHandler = signal.signal(signal.SIGHUP, self.sighupHandler)
         self.log_warn("Starting group membership cacher service")
         service.Service.startService(self)
         return self.update()
 
-    @inlineCallbacks
-    def update(self):
-        self.nextUpdate = None
-        try:
-            yield self.updateMethod()
-        finally:
-            self.log_info("Scheduling next group membership update")
-            self.nextUpdate = self.reactor.callLater(self.updateSeconds,
-                self.update)
+    def sighupHandler(self, num, frame):
+        self.reactor.callFromThread(self.update)
 
     def stopService(self):
+        signal.signal(signal.SIGHUP, self.previousHandler)
         self.log_warn("Stopping group membership cacher service")
         service.Service.stopService(self)
         if self.nextUpdate is not None:
             self.nextUpdate.cancel()
+            self.nextUpdate = None
 
+    @inlineCallbacks
+    def update(self):
+        """
+        A wrapper around updateCache, this method manages the scheduling of the
+        subsequent update, as well as prevents multiple updates from running
+        simultaneously, which could otherwise happen because SIGHUP now triggers
+        an update on demand.  If update is called while an update is in progress,
+        as soon as the first update is finished a new one is started.  Otherwise,
+        when an update finishes and there is not another one waiting, the next
+        update is scheduled for updateSeconds in the future.
 
+        @return: True if an update was already in progress, False otherwise
+        @rtype: C{bool}
+        """
 
+        self.log_debug("Group membership update called")
+
+        # A call to update while an update is in progress sets the updateAwaiting flag
+        # so that an update happens again right after the current one is complete.
+        if self.updateInProgress:
+            self.updateAwaiting = True
+            returnValue(True)
+
+        self.nextUpdate = None
+        self.updateInProgress = True
+        self.updateAwaiting = False
+        try:
+            yield self.updateMethod()
+        finally:
+            self.updateInProgress = False
+            if self.updateAwaiting:
+                self.log_info("Performing group membership update")
+                yield self.update()
+            else:
+                self.log_info("Scheduling next group membership update")
+                self.nextUpdate = self.reactor.callLater(self.updateSeconds,
+                    self.update)
+        returnValue(False)
+
 class GroupMembershipCacherServiceMaker(LoggingMixIn):
     """
     Configures and returns a GroupMembershipCacherService
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20120730/247fff17/attachment.html>


More information about the calendarserver-changes mailing list