[CalendarServer-changes] [8578] CalendarServer/branches/users/glyph/parallel-upgrade_to_1

source_changes at macosforge.org source_changes at macosforge.org
Tue Jan 24 00:57:46 PST 2012


Revision: 8578
          http://trac.macosforge.org/projects/calendarserver/changeset/8578
Author:   glyph at apple.com
Date:     2012-01-24 00:57:46 -0800 (Tue, 24 Jan 2012)
Log Message:
-----------
add spawnWithConfig so that we don't need to request a store in the subprocess if we just want to propagate a configuration

Modified Paths:
--------------
    CalendarServer/branches/users/glyph/parallel-upgrade_to_1/calendarserver/tap/cfgchild.py
    CalendarServer/branches/users/glyph/parallel-upgrade_to_1/txdav/common/datastore/upgrade/migrate.py
    CalendarServer/branches/users/glyph/parallel-upgrade_to_1/txdav/common/datastore/upgrade/test/test_migrate.py

Modified: CalendarServer/branches/users/glyph/parallel-upgrade_to_1/calendarserver/tap/cfgchild.py
===================================================================
--- CalendarServer/branches/users/glyph/parallel-upgrade_to_1/calendarserver/tap/cfgchild.py	2012-01-24 08:57:17 UTC (rev 8577)
+++ CalendarServer/branches/users/glyph/parallel-upgrade_to_1/calendarserver/tap/cfgchild.py	2012-01-24 08:57:46 UTC (rev 8578)
@@ -29,7 +29,7 @@
 from calendarserver.tools.util import setupMemcached
 from twisted.python.reflect import namedAny, qual
 from twisted.internet.defer import inlineCallbacks, returnValue
-from twisted.protocols.amp import AMP, Command, String, Integer#, ListOf
+from twisted.protocols.amp import AMP, Command, String, Integer, Boolean
 from txdav.common.datastore.upgrade.migrate import (
     StoreSpawnerService, swapAMP
 )
@@ -61,6 +61,7 @@
 
         ## shared connection pool!
         ("connectionPoolFD", Integer(optional=True)),
+        ("withStore", Boolean()),
     ]
 
 
@@ -83,7 +84,7 @@
 
     @ConfigureChild.responder
     def conf(self, delegateTo, pidFile, logID, configFile, processCount,
-             connectionPoolFD=None):
+             connectionPoolFD=None, withStore=True):
         """
         Load the current config file into this child process, create a store
         based on it, and delegate to the upgrade logic.
@@ -107,19 +108,21 @@
             changedConfig.update(DBAMPFD=connectionPoolFD)
         self.config.updateDefaults(changedConfig)
 
-        # Construct and start database pool and store.
-        pool, txnf = getDBPool(self.config)
-        if pool is not None:
-            from twisted.internet import reactor
-            pool.startService()
-            reactor.addSystemEventTrigger(
-                "before", "shutdown", pool.stopService
-            )
-        dbstore = storeFromConfig(self.config, txnf)
-
+        if withStore:
+            # Construct and start database pool and store.
+            pool, txnf = getDBPool(self.config)
+            if pool is not None:
+                from twisted.internet import reactor
+                pool.startService()
+                reactor.addSystemEventTrigger(
+                    "before", "shutdown", pool.stopService
+                )
+            delegateArg = storeFromConfig(self.config, txnf)
+        else:
+            delegateArg = self.config
         # Finally, construct the class we're supposed to delegate to.
         delegateClass = namedAny(delegateTo)
-        swapAMP(self, delegateClass(dbstore))
+        swapAMP(self, delegateClass(delegateArg))
         return {}
 
 
@@ -148,11 +151,25 @@
         self.config = config
 
 
-    @inlineCallbacks
+    def spawnWithConfig(self, config, here, there):
+        """
+        Spawn the child with a configuration.
+        """
+        return self._doSpawn(config, here, there, False)
+
+
     def spawnWithStore(self, here, there):
         """
         Spawn the child with a store based on a configuration.
         """
+        return self._doSpawn(self.config, here, there, True)
+
+
+    @inlineCallbacks
+    def _doSpawn(self, config, here, there, withStore):
+        """
+        Common implementation of L{spawnWithStore} and L{spawnWithConfig}.
+        """
         thisID = self.nextID
         self.nextID += 1
         if self.dispenser is not None:
@@ -178,8 +195,9 @@
             delegateTo=qual(there),
             pidFile="%s-migrator-%s" % (self.maker.tapname, thisID),
             logID="migrator-%s" % (thisID,),
-            configFile=self.config.getProvider().getConfigFileName(),
-            processCount=self.config.MultiProcess.ProcessCount,
+            configFile=config.getProvider().getConfigFileName(),
+            processCount=config.MultiProcess.ProcessCount,
+            withStore=withStore,
             **extra
         )
         returnValue(swapAMP(controller, here))

Modified: CalendarServer/branches/users/glyph/parallel-upgrade_to_1/txdav/common/datastore/upgrade/migrate.py
===================================================================
--- CalendarServer/branches/users/glyph/parallel-upgrade_to_1/txdav/common/datastore/upgrade/migrate.py	2012-01-24 08:57:17 UTC (rev 8577)
+++ CalendarServer/branches/users/glyph/parallel-upgrade_to_1/txdav/common/datastore/upgrade/migrate.py	2012-01-24 08:57:46 UTC (rev 8578)
@@ -92,7 +92,16 @@
         raise NotImplementedError("subclasses must implement the specifics")
 
 
+    def spawnWithConfig(self, config, here, there):
+        """
+        Like L{SpawnerService.spawn}, but instead of instantiating C{there}
+        with 0 arguments, it instantiates it with the given
+        L{twistedcaldav.config.Config}.
+        """
+        raise NotImplementedError("subclasses must implement the specifics")
 
+
+
 class Configure(Command):
     """
     Configure the upgrade helper process.
@@ -162,8 +171,8 @@
         super(UpgradeHelperProcess, self).__init__()
         self.store = store
         self.store.setMigrating(True)
-        
 
+
     @Configure.responder
     def configure(self, filename, appropriateStoreClass):
         subsvc = None

Modified: CalendarServer/branches/users/glyph/parallel-upgrade_to_1/txdav/common/datastore/upgrade/test/test_migrate.py
===================================================================
--- CalendarServer/branches/users/glyph/parallel-upgrade_to_1/txdav/common/datastore/upgrade/test/test_migrate.py	2012-01-24 08:57:17 UTC (rev 8577)
+++ CalendarServer/branches/users/glyph/parallel-upgrade_to_1/txdav/common/datastore/upgrade/test/test_migrate.py	2012-01-24 08:57:46 UTC (rev 8578)
@@ -20,6 +20,7 @@
 
 from twext.python.filepath import CachingFilePath
 from twext.web2.http_headers import MimeType
+from twext.enterprise.adbapi2 import Pickle
 
 from twisted.python.modules import getModule
 from twisted.application.service import Service, MultiService
@@ -28,6 +29,8 @@
 from twisted.protocols.amp import AMP, Command, String
 from twisted.python.reflect import qual, namedAny
 from twisted.trial.unittest import TestCase
+
+
 from txdav.caldav.datastore.test.common import CommonTests
 from txdav.carddav.datastore.test.common import CommonTests as ABCommonTests
 from txdav.common.datastore.file import CommonDataStore
@@ -50,7 +53,15 @@
     arguments = [('delegateTo', String())]
 
 
+class PickleConfig(Command):
+    """
+    Unpickle some configuration in a subprocess.
+    """
+    arguments = [('delegateTo', String()),
+                 ('config', Pickle())]
 
+
+
 class StoreCreator(AMP):
     """
     Helper protocol.
@@ -65,25 +76,49 @@
         return {}
 
 
+    @PickleConfig.responder
+    def pickleConfig(self, config, delegateTo):
+        #from twistedcaldav.config import config as globalConfig
+        #globalConfig._data = config._data
+        swapAMP(self, namedAny(delegateTo)(config))
+        return {}
 
+
+
 class StubSpawner(StoreSpawnerService):
     """
     Stub spawner service which populates the store forcibly.
     """
 
+    def __init__(self, config=None):
+        super(StubSpawner, self).__init__()
+        self.config = config
+
+
     @inlineCallbacks
     def spawnWithStore(self, here, there):
         """
-        'here' and 'there' are the helper protocols; in a slight modification
-        of the signature, 'there' will expect to be created with an instance of
-        a store.
+        'here' and 'there' are the helper protocols 'there' will expect to be
+        created with an instance of a store.
         """
         master = yield self.spawn(AMP(), StoreCreator)
         yield master.callRemote(CreateStore, delegateTo=qual(there))
         returnValue(swapAMP(master, here))
 
 
+    @inlineCallbacks
+    def spawnWithConfig(self, config, here, there):
+        """
+        Similar to spawnWithStore except the child process gets a configuration
+        object instead.
+        """
+        master = yield self.spawn(AMP(), StoreCreator)
+        yield master.callRemote(PickleConfig, config=self.config,
+                                delegateTo=qual(there))
+        returnValue(swapAMP(master, here))
 
+
+
 class HomeMigrationTests(TestCase):
     """
     Tests for L{UpgradeToDatabaseService}.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20120124/233e20ff/attachment-0001.html>


More information about the calendarserver-changes mailing list