Merge "sync periodic_task fix from incubator"
This commit is contained in:
commit
4c22c8cb28
@ -11,6 +11,7 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import random
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from oslo.config import cfg
|
from oslo.config import cfg
|
||||||
@ -80,14 +81,14 @@ def periodic_task(*args, **kwargs):
|
|||||||
return f
|
return f
|
||||||
|
|
||||||
# NOTE(sirp): The `if` is necessary to allow the decorator to be used with
|
# NOTE(sirp): The `if` is necessary to allow the decorator to be used with
|
||||||
# and without parents.
|
# and without parenthesis.
|
||||||
#
|
#
|
||||||
# In the 'with-parents' case (with kwargs present), this function needs to
|
# In the 'with-parenthesis' case (with kwargs present), this function needs
|
||||||
# return a decorator function since the interpreter will invoke it like:
|
# to return a decorator function since the interpreter will invoke it like:
|
||||||
#
|
#
|
||||||
# periodic_task(*args, **kwargs)(f)
|
# periodic_task(*args, **kwargs)(f)
|
||||||
#
|
#
|
||||||
# In the 'without-parents' case, the original function will be passed
|
# In the 'without-parenthesis' case, the original function will be passed
|
||||||
# in as the first argument, like:
|
# in as the first argument, like:
|
||||||
#
|
#
|
||||||
# periodic_task(f)
|
# periodic_task(f)
|
||||||
@ -142,6 +143,27 @@ class _PeriodicTasksMeta(type):
|
|||||||
cls._periodic_spacing[name] = task._periodic_spacing
|
cls._periodic_spacing[name] = task._periodic_spacing
|
||||||
|
|
||||||
|
|
||||||
|
def _nearest_boundary(last_run, spacing):
|
||||||
|
"""Find nearest boundary which is in the past, which is a multiple of the
|
||||||
|
spacing with the last run as an offset.
|
||||||
|
|
||||||
|
Eg if last run was 10 and spacing was 7, the new last run could be: 17, 24,
|
||||||
|
31, 38...
|
||||||
|
|
||||||
|
0% to 5% of the spacing value will be added to this value to ensure tasks
|
||||||
|
do not synchronize. This jitter is rounded to the nearest second, this
|
||||||
|
means that spacings smaller than 20 seconds will not have jitter.
|
||||||
|
"""
|
||||||
|
current_time = time.time()
|
||||||
|
if last_run is None:
|
||||||
|
return current_time
|
||||||
|
delta = current_time - last_run
|
||||||
|
offset = delta % spacing
|
||||||
|
# Add up to 5% jitter
|
||||||
|
jitter = int(spacing * (random.random() / 20))
|
||||||
|
return current_time - offset + jitter
|
||||||
|
|
||||||
|
|
||||||
@six.add_metaclass(_PeriodicTasksMeta)
|
@six.add_metaclass(_PeriodicTasksMeta)
|
||||||
class PeriodicTasks(object):
|
class PeriodicTasks(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -159,17 +181,18 @@ class PeriodicTasks(object):
|
|||||||
spacing = self._periodic_spacing[task_name]
|
spacing = self._periodic_spacing[task_name]
|
||||||
last_run = self._periodic_last_run[task_name]
|
last_run = self._periodic_last_run[task_name]
|
||||||
|
|
||||||
# If a periodic task is _nearly_ due, then we'll run it early
|
# Check if due, if not skip
|
||||||
idle_for = min(idle_for, spacing)
|
idle_for = min(idle_for, spacing)
|
||||||
if last_run is not None:
|
if last_run is not None:
|
||||||
delta = last_run + spacing - time.time()
|
delta = last_run + spacing - time.time()
|
||||||
if delta > 0.2:
|
if delta > 0:
|
||||||
idle_for = min(idle_for, delta)
|
idle_for = min(idle_for, delta)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
LOG.debug("Running periodic task %(full_task_name)s",
|
LOG.debug("Running periodic task %(full_task_name)s",
|
||||||
{"full_task_name": full_task_name})
|
{"full_task_name": full_task_name})
|
||||||
self._periodic_last_run[task_name] = time.time()
|
self._periodic_last_run[task_name] = _nearest_boundary(
|
||||||
|
last_run, spacing)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
task(self, context)
|
task(self, context)
|
||||||
|
Loading…
Reference in New Issue
Block a user