コード例 #1
0
 def process_timer(self, interval, tick, prev="", next=""):
     """
   Call tic() every x seconds. x is defined in self.interval
   This method is called by TimerService in the interval given
   in zope.conf. The Default is every 5 seconds.
 """
     if not last_tic_lock.acquire(0):
         return
     try:
         # make sure our skin is set-up. On CMF 1.5 it's setup by acquisition,
         # but on 2.2 it's by traversal, and our site probably wasn't traversed
         # by the timerserver request, which goes into the Zope Control_Panel
         # calling it a second time is a harmless and cheap no-op.
         # both setupCurrentSkin and REQUEST are acquired from containers.
         self.setupCurrentSkin(self.REQUEST)
         # only start when we are the alarmNode
         alarmNode = self.getAlarmNode()
         current_node = getCurrentNode()
         global _check_upgrade
         if alarmNode == '':
             self.setAlarmNode(current_node)
             alarmNode = current_node
         if alarmNode == current_node:
             global last_tic
             now = tick.timeTime()
             if now - last_tic >= self.interval:
                 self.tic()
                 last_tic = now
         elif _check_upgrade and self.getServerAddress() == alarmNode:
             # BBB: check (once per run) if our node was alarm_node by address, and
             # migrate it.
             _check_upgrade = False
             self.setAlarmNode(current_node)
     finally:
         last_tic_lock.release()
コード例 #2
0
 def getOtherZopeNode(self):
     from Products.CMFActivity.ActivityTool import getCurrentNode
     activity_tool = self.portal.portal_activities
     node_list = list(activity_tool.getProcessingNodeList())
     node_list.remove(getCurrentNode())
     assert node_list, "this unit test must be run with at least 2 Zope nodes"
     return node_list[0]
コード例 #3
0
 def tic(self, processing_node=1, force=0):
     processing_node_list = self.getProcessingNodeList()
     if len(processing_node_list) > 1 and \
        getCurrentNode() == self.getDistributingNode():
         # Sleep between each distribute.
         time.sleep(0.3)
         transaction.commit()
         transaction.begin()
     else:
         self._orig_tic(processing_node, force)
コード例 #4
0
    def getOtherZopeNodeList(self, node_count=2):
        """Wait for at least `node_count` (including the current node) to be
    registered on portal activities and return the list of their node ids.

    This aborts current transaction.
    """
        for i in xrange(30):
            node_list = list(
                self.portal.portal_activities.getProcessingNodeList())
            if len(node_list) >= node_count:
                node_list.remove(getCurrentNode())
                return node_list
            self.abort()
            time.sleep(i * 0.1)
        self.fail("No other activity node registered, make sure you are using"
                  " --activity_node=%s command line flag" % node_count)
コード例 #5
0
 def _registerNode(self, distributing, processing):
     """Register node to process and/or distribute activities"""
     try:
         activity_tool = self.portal.portal_activities
     except AttributeError:
         from Products.CMFActivity.ActivityTool import ActivityTool
         activity_tool = ActivityTool().__of__(self.app)
     currentNode = getCurrentNode()
     if distributing:
         activity_tool.manage_setDistributingNode(currentNode)
     elif currentNode == activity_tool.getDistributingNode():
         activity_tool.manage_setDistributingNode('')
     if processing:
         activity_tool.manage_addToProcessingList((currentNode, ))
     else:
         activity_tool.manage_delNode((currentNode, ))
コード例 #6
0
    def testLateInvalidationFromZEO(self):
        ### Check unit test is run properly
        from ZEO.ClientStorage import ClientStorage
        from Products.CMFActivity.ActivityTool import getCurrentNode
        storage = self.portal._p_jar._storage
        activity_tool = self.portal.portal_activities
        node_list = list(activity_tool.getProcessingNodeList())
        node_list.remove(getCurrentNode())
        assert node_list and isinstance(storage, ClientStorage), \
          "this unit test must be run with at least 2 ZEO clients"

        ### Prepare unit test, to minimize amount of work during critical section
        ## url to create some content using another zope
        new_content_url = "http://ERP5TypeTestCase:@%s%s/Folder_create" % (
            node_list[0], self.portal.organisation_module.getPath())
        ## prepare freeze/unfreeze of ZEO storage
        zeo_connection = storage._connection
        socket_map = zeo_connection._map
        freeze_lock = threading.Lock()
        freeze_lock.acquire()

        def unfreezeStorage():
            socket_map[zeo_connection.fileno()] = zeo_connection
            # wake up asyncore loop to take the new socket into account
            zeo_connection.trigger.pull_trigger()

        # link to ZEO will be unfrozen 1 second after we read 'message' table
        unfreeze_timer = threading.Timer(1, unfreezeStorage)
        unfreeze_timer.setDaemon(True)
        ## prepare monkey-patches (with code to revert them)
        from Products.CMFActivity.Activity.SQLDict import SQLDict
        zeo_server = storage._server

        def unpatch():
            storage._server = zeo_server
            SQLDict.getProcessableMessageList = SQLDict_getProcessableMessageList

        SQLDict_getProcessableMessageList = SQLDict.getProcessableMessageList

        def getProcessableMessageList(*args, **kw):
            result = SQLDict_getProcessableMessageList(*args, **kw)
            unpatch()
            unfreeze_timer.start()
            return result

        ### Perform unit test
        ## we should start without any pending activity
        self.assertNoPendingMessage()
        ## monkey-patch ...
        SQLDict.getProcessableMessageList = getProcessableMessageList
        try:
            # prevent nodes from processing activities automatically
            activity_tool.manage_removeFromProcessingList(node_list)
            self.commit()
            del socket_map[zeo_connection.fileno()]
            try:
                # wake up asyncore loop and wait we really woke up
                zeo_connection.trigger.pull_trigger(freeze_lock.release)
                freeze_lock.acquire()
                # make sure ZODB is not accessed until we get a message to process
                storage._server = None
                # ... monkey-patch done
                ## create object
                urllib.urlopen(new_content_url).read()
                ## validate reindex activity
                activity_tool.distribute()
                self.assertEqual(1, len(activity_tool.getMessageList()))
                ## reindex created object
                activity_tool.tic()
            finally:
                try:
                    unfreeze_timer.join()
                except RuntimeError:
                    unfreezeStorage()
        finally:
            unpatch()
            activity_tool.manage_addToProcessingList(node_list)
            self.commit()
        ## When the bug is not fixed, we get a -3 failed activity
        self.assertNoPendingMessage()