Also, note that the actual code that's starting and setting the
interval is here:
/usr/lib/python2.7/site-packages/cinder/service.py
~~~
from oslo_service import loopingcall
(...)
if self.periodic_interval:
if self.periodic_fuzzy_delay: initial_delay = random.randint(0, self.periodic_fuzzy_delay)
else: initial_delay = None
And from LoopingCallBase
~~~
def _start(self, idle_for, initial_delay=None, stop_on_exception=True):
"""Start the looping
:param idle_for: Callable that takes two positional arguments, returns how long to idle for. The first positional argument is the last result from the function being looped and the second positional argument is the time it took to calculate that result.
:param initial_delay: How long to delay before starting the looping. Value is in seconds.
:param stop_on_exception: Whether to stop if an exception occurs.
:returns: eventlet event instance
"""
if self._thread is not None:
raise RuntimeError(self._RUN_ONLY_ONE_MESSAGE) self._running = True
self.done = event.Event() self._thread = greenthread.spawn( self._run_loop, idle_for, initial_delay=initial_delay, stop_on_exception=stop_on_exception) self._thread.link(self._on_done)
return self.done
(...)
def _run_loop(self, idle_for_func, initial_delay=None, stop_on_exception=True):
kind = self._KIND
func_name = reflection.get_callable_name(self.f)
func = self.f if stop_on_exception else _safe_wrapper(self.f, kind, func_name)
if initial_delay: greenthread.sleep(initial_delay)
try:
watch = timeutils.StopWatch()
while self._running: watch.restart() result = func(*self.args, **self.kw) watch.stop()
if not self._running: break idle = idle_for_func(result, watch.elapsed()) LOG.trace('%(kind)s %(func_name)r sleeping ' 'for %(idle).02f seconds', {'func_name': func_name, 'idle': idle, 'kind': kind}) greenthread.sleep(idle)
except LoopingCallDone as e: self.done.send(e.retvalue)
except Exception: exc_info = sys.exc_info()
try: LOG.error(_LE('%(kind)s %(func_name)r failed'), {'kind': kind, 'func_name': func_name}, exc_info=exc_info) self.done.send_exception(*exc_info) finally:
del exc_info
return
else: self.done.send(True)
(...)
~~~
Also, note that the actual code that's starting and setting the python2. 7/site- packages/ cinder/ service. py interval: fuzzy_delay:
initial_ delay = random.randint(0, self.periodic_ fuzzy_delay)
initial_ delay = None
interval is here:
/usr/lib/
~~~
from oslo_service import loopingcall
(...)
if self.periodic_
if self.periodic_
else:
~~~
/usr/lib/ python2. 7/site- packages/ oslo_service/ loopingcall. py:class opingCall( LoopingCallBase ): opingCall( LoopingCallBase ):
FixedIntervalLo
~~~
class FixedIntervalLo
"""A fixed interval looping call."""
_RUN_ ONLY_ONE_ MESSAGE = _("A fixed interval looping call can only run"
" one function at a time")
_KIND = _('Fixed interval looping call')
def start(self, interval, initial_delay=None, stop_on_ exception= True):
func_ name = reflection. get_callable_ name(self. f)
LOG.warning( _LW('Function %(func_name)r run outlasted '
'interval by %(delay).2f sec'),
{'func_ name': func_name, 'delay': delay}) _idle_for, initial_ delay=initial_ delay,
stop_ on_exception= stop_on_ exception)
def _idle_for(result, elapsed):
delay = round(elapsed - interval, 2)
if delay > 0:
return -delay if delay < 0 else 0
return self._start(
~~~
And from LoopingCallBase exception= True):
~~~
def _start(self, idle_for, initial_delay=None, stop_on_
"""Start the looping
:param idle_for: Callable that takes two positional arguments, returns
how long to idle for. The first positional argument is
the last result from the function being looped and the
second positional argument is the time it took to
calculate that result.
Value is in seconds. self._RUN_ ONLY_ONE_ MESSAGE)
self._ running = True
self._ thread = greenthread.spawn(
self. _run_loop, idle_for,
initial_ delay=initial_ delay, stop_on_ exception= stop_on_ exception)
self._ thread. link(self. _on_done)
initial_ delay=None, stop_on_ exception= True): get_callable_ name(self. f) self.f, kind,
func_ name)
greenthrea d.sleep( initial_ delay) StopWatch( )
watch. restart( )
result = func(*self.args, **self.kw)
watch. stop()
break
idle = idle_for_ func(result, watch.elapsed())
LOG.trace( '%(kind) s %(func_name)r sleeping '
'for %(idle).02f seconds',
{' func_name' : func_name, 'idle': idle,
' kind': kind})
greenthread. sleep(idle)
self. done.send( e.retvalue)
exc_ info = sys.exc_info()
LOG.error( _LE('%( kind)s %(func_name)r failed'),
{' kind': kind, 'func_name': func_name},
exc_ info=exc_ info)
self. done.send_ exception( *exc_info)
finally:
self. done.send( True)
:param initial_delay: How long to delay before starting the looping.
:param stop_on_exception: Whether to stop if an exception occurs.
:returns: eventlet event instance
"""
if self._thread is not None:
raise RuntimeError(
self.done = event.Event()
return self.done
(...)
def _run_loop(self, idle_for_func,
kind = self._KIND
func_name = reflection.
func = self.f if stop_on_exception else _safe_wrapper(
if initial_delay:
try:
watch = timeutils.
while self._running:
if not self._running:
except LoopingCallDone as e:
except Exception:
try:
del exc_info
return
else:
(...)
~~~