Comment 2 for bug 1695018

Revision history for this message
Andreas Karis (akaris) wrote :

/usr/lib/python2.7/site-packages/oslo_service/periodic_task.py
~~~
    def run_periodic_tasks(self, context, raise_on_error=False):
        """Tasks to be run at a periodic interval."""
        idle_for = DEFAULT_INTERVAL
        for task_name, task in self._periodic_tasks:
            if (task._periodic_external_ok and not
               self.conf.run_external_periodic_tasks):
                continue
            cls_name = reflection.get_class_name(self, fully_qualified=False)
            full_task_name = '.'.join([cls_name, task_name])

            spacing = self._periodic_spacing[task_name]
            last_run = self._periodic_last_run[task_name]

            # Check if due, if not skip
            idle_for = min(idle_for, spacing)
            if last_run is not None:
                delta = last_run + spacing - now()
                if delta > 0:
                    idle_for = min(idle_for, delta)
                    continue

            LOG.debug("Running periodic task %(full_task_name)s",
                      {"full_task_name": full_task_name})
            self._periodic_last_run[task_name] = _nearest_boundary(
                last_run, spacing)

            try:
                task(self, context)
            except Exception:
                if raise_on_error:
                    raise
                LOG.exception(_LE("Error during %(full_task_name)s"),
                              {"full_task_name": full_task_name})
            time.sleep(0)

        return idle_for
~~~

Sets a minimum interval of spacing for periodic task

~~~
[root@overcloud-controller-1 ~]# grep run_periodic_tasks /usr/lib/python2.7/site-packages/cinder/* -R
/usr/lib/python2.7/site-packages/cinder/manager.py: return self.run_periodic_tasks(context, raise_on_error=raise_on_error)
~~~
~~~
class Manager(base.Base, PeriodicTasks):
    # Set RPC API version to 1.0 by default.
    RPC_API_VERSION = '1.0'

    target = messaging.Target(version=RPC_API_VERSION)

    def __init__(self, host=None, db_driver=None, cluster=None):
        if not host:
            host = CONF.host
        self.host = host
        self.cluster = cluster
        self.additional_endpoints = []
        super(Manager, self).__init__(db_driver)

    def periodic_tasks(self, context, raise_on_error=False):
        """Tasks to be run at a periodic interval."""
        return self.run_periodic_tasks(context, raise_on_error=raise_on_error)
~~~

/usr/lib/python2.7/site-packages/cinder/service.py
~~~
        if self.periodic_interval:
            if self.periodic_fuzzy_delay:
                initial_delay = random.randint(0, self.periodic_fuzzy_delay)
            else:
                initial_delay = None

            periodic = loopingcall.FixedIntervalLoopingCall(
                self.periodic_tasks)
            periodic.start(interval=self.periodic_interval,
                           initial_delay=initial_delay)
            self.timers.append(periodic)
(...)
    def periodic_tasks(self, raise_on_error=False):
        """Tasks to be run at a periodic interval."""
        ctxt = context.get_admin_context()
        self.manager.periodic_tasks(ctxt, raise_on_error=raise_on_error)
~~~

If I understand the code correctly, then the above means that:
- set up a looping call with interval=periodic_interval that executes periodic tasks
- periodic tasks themselves have a minimum spacing, they cannot be run more often than this

==> max(spacing;periodic_interval) is the value that we get for running periodic_tasks in cinder, meaning that we cannot get lower than 60 seconds with the defaults