periodic_interval only works at a minimum of 60 seconds for periodic_tasks
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Cinder |
Fix Released
|
Undecided
|
Sean McGinnis | ||
OpenStack Shared File Systems Service (Manila) |
Opinion
|
Undecided
|
Unassigned |
Bug Description
periodic_interval only works at a minimum of 60 seconds for periodic_tasks
This bug report is a bit the contrary of https:/
I found this one here that explains periodic_task:
http://
Default interval for periodic_tasks is DEFAULT_INTERVAL = 60.0 in:
/usr/lib/
~~~
def periodic_
"""Decorator to indicate that a method is a periodic task.
This decorator can be used in two ways:
1. Without arguments '@periodic_task', this will be run on the default
interval of 60 seconds.
2. With arguments:
[, name=[None|
this will be run on approximately every N seconds. If this number is
negative the periodic task will be disabled. If the run_immediately
argument is provided and has a value of 'True', the first run of the
task will be shortly after task scheduler starts. If
task runs will be approximately N seconds after the task scheduler
starts. If name is not provided, __name__ of function is used.
~~~
I then identified the way for how to set spacing=7 in the code without
a change to oslo, but to cinder:
~~~
@periodic_
def _publish_
"""Pass data back to the scheduler at a periodic interval."""
if self.last_
~~~
At the same time, I had set
~~~
# Interval, in seconds, between running periodic tasks (integer value)
periodic_interval = 1
~~~
~~~
[root@overcloud
'Notifying Schedulers of'
2017-06-01 14:17:43.485 728707 DEBUG cinder.manager
[req-9bb3127a-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 14:18:55.573 754824 DEBUG cinder.manager
[req-edf8d804-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 14:19:01.136 754824 DEBUG cinder.manager
[req-506d4d24-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 14:19:08.140 754824 DEBUG cinder.manager
[req-506d4d24-
Schedulers of capabilities ... _publish_
/usr/lib/
^C
~~~
Every 7 seconds!
+++++++
Another test:
~~~
@periodic_
def _publish_
"""Pass data back to the scheduler at a periodic interval."""
if self.last_
~~~
~~~
# Interval, in seconds, between running periodic tasks (integer value)
periodic_interval = 60
~~~
~~~
2017-06-01 14:21:10.565 762982 DEBUG cinder.manager
[req-9bed93b0-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 14:21:43.106 762982 DEBUG cinder.manager
[req-c9129a1f-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 14:22:43.105 762982 DEBUG cinder.manager
[req-c9129a1f-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 14:23:43.109 762982 DEBUG cinder.manager
[req-c9129a1f-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 14:24:43.107 762982 DEBUG cinder.manager
[req-c9129a1f-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 14:25:43.108 762982 DEBUG cinder.manager
[req-c9129a1f-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 14:26:43.107 762982 DEBUG cinder.manager
[req-c9129a1f-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 14:27:43.105 762982 DEBUG cinder.manager
[req-c9129a1f-
Schedulers of capabilities ... _publish_
/usr/lib/
~~~
Every 60 seconds!
+++++++
Another test:
~~~
@periodic_
def _publish_
"""Pass data back to the scheduler at a periodic interval."""
if self.last_
~~~
~~~
# Interval, in seconds, between running periodic tasks (integer value)
periodic_interval = 20
~~~
~~~
2017-06-01 14:30:17.177 794013 DEBUG cinder.manager
[req-d33cae0c-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 14:30:37.178 794013 DEBUG cinder.manager
[req-d33cae0c-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 14:30:57.180 794013 DEBUG cinder.manager
[req-d33cae0c-
Schedulers of capabilities ... _publish_
/usr/lib/
~~~
Every 20 seconds!
+++++++
Another test:
~~~
@periodic_
def _publish_
"""Pass data back to the scheduler at a periodic interval."""
if self.last_
~~~
~~~
# Interval, in seconds, between running periodic tasks (integer value)
periodic_interval = 10
~~~
~~~
2017-06-01 14:34:37.227 794013 DEBUG cinder.manager
[req-d33cae0c-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 14:35:01.675 812757 DEBUG cinder.manager
[req-c908e529-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 14:35:15.247 812757 DEBUG cinder.manager
[req-7ca46b1e-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 14:35:25.253 812757 DEBUG cinder.manager
[req-7ca46b1e-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 14:35:35.254 812757 DEBUG cinder.manager
[req-7ca46b1e-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 14:35:45.260 812757 DEBUG cinder.manager
[req-7ca46b1e-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 14:35:55.263 812757 DEBUG cinder.manager
[req-7ca46b1e-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 14:36:05.266 812757 DEBUG cinder.manager
[req-7ca46b1e-
Schedulers of capabilities ... _publish_
/usr/lib/
~~~
Every 10 seconds!
+++++++
Another test:
~~~
@periodic_
def _publish_
"""Pass data back to the scheduler at a periodic interval."""
if self.last_
~~~
~~~
# Interval, in seconds, between running periodic tasks (integer value)
periodic_interval = 3
~~~
~~~
2017-06-01 14:39:10.412 820628 DEBUG cinder.manager
[req-a9cb98c3-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 14:39:13.411 820628 DEBUG cinder.manager
[req-a9cb98c3-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 14:39:19.415 820628 DEBUG cinder.manager
[req-a9cb98c3-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 14:39:25.415 820628 DEBUG cinder.manager
[req-a9cb98c3-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 14:39:28.413 820628 DEBUG cinder.manager
[req-a9cb98c3-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 14:39:34.417 820628 DEBUG cinder.manager
[req-a9cb98c3-
Schedulers of capabilities ... _publish_
/usr/lib/
~~~
Every 3 and every 6 seconds ????
+++++++
Another test:
~~~
@periodic_
def _publish_
"""Pass data back to the scheduler at a periodic interval."""
if self.last_
~~~
~~~
# Interval, in seconds, between running periodic tasks (integer value)
periodic_interval = 5
~~~
~~~
2017-06-01 14:42:03.285 836505 DEBUG cinder.manager
[req-fb8dc561-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 14:42:08.289 836505 DEBUG cinder.manager
[req-fb8dc561-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 14:42:13.292 836505 DEBUG cinder.manager
[req-fb8dc561-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 14:42:18.296 836505 DEBUG cinder.manager
[req-fb8dc561-
Schedulers of capabilities ... _publish_
/usr/lib/
~~~
Every 5 seconds
+++++++
Another test:
~~~
@periodic_
def _publish_
"""Pass data back to the scheduler at a periodic interval."""
if self.last_
~~~
~~~
# Interval, in seconds, between running periodic tasks (integer value)
periodic_interval = 1
~~~
2017-06-01 14:43:27.188 843269 DEBUG cinder.manager
[req-d5dfe1a2-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 14:44:24.995 843269 DEBUG cinder.manager
[req-e419755a-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 14:45:25.034 843269 DEBUG cinder.manager
[req-e419755a-
Schedulers of capabilities ... _publish_
/usr/lib/
~~~
Every 60 seconds!
+++++++
Another test:
~~~
@periodic_
def _publish_
"""Pass data back to the scheduler at a periodic interval."""
if self.last_
~~~
~~~
# Interval, in seconds, between running periodic tasks (integer value)
periodic_interval = 1
~~~
2017-06-01 14:47:32.624 858210 DEBUG cinder.manager
[req-df539f1d-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 14:48:31.180 858210 DEBUG cinder.manager
[req-3c9c2291-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 14:49:33.221 858210 DEBUG cinder.manager
[req-3c9c2291-
Schedulers of capabilities ... _publish_
/usr/lib/
~~~
Every 60 seconds!
+++++++
Another test:
~~~
@periodic_
def _publish_
"""Pass data back to the scheduler at a periodic interval."""
if self.last_
~~~
~~~
# Interval, in seconds, between running periodic tasks (integer value)
periodic_interval = 90
~~~
~~~
2017-06-01 14:52:51.813 869318 DEBUG cinder.manager
[req-e9c7247c-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 14:54:21.812 869318 DEBUG cinder.manager
[req-e9c7247c-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 14:55:51.810 869318 DEBUG cinder.manager
[req-e9c7247c-
Schedulers of capabilities ... _publish_
/usr/lib/
~~~
Every 90 seconds!
+++++++
Another test:
~~~
@periodic_
def _publish_
"""Pass data back to the scheduler at a periodic interval."""
if self.last_
~~~
~~~
# Interval, in seconds, between running periodic tasks (integer value)
periodic_interval = 17
~~~
~~~
2017-06-01 14:57:31.063 893811 DEBUG cinder.manager
[req-13d6e949-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 14:57:48.065 893811 DEBUG cinder.manager
[req-13d6e949-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 14:58:05.072 893811 DEBUG cinder.manager
[req-13d6e949-
Schedulers of capabilities ... _publish_
/usr/lib/
~~~
Every 17 seconds!
+++++++
Another test:
~~~
@periodic_
def _publish_
"""Pass data back to the scheduler at a periodic interval."""
if self.last_
~~~
~~~
# Interval, in seconds, between running periodic tasks (integer value)
periodic_interval = 4
~~~
~~~
2017-06-01 15:00:27.939 902534 DEBUG cinder.manager
[req-15b9009c-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 15:00:31.940 902534 DEBUG cinder.manager
[req-15b9009c-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 15:00:35.945 902534 DEBUG cinder.manager
[req-15b9009c-
Schedulers of capabilities ... _publish_
/usr/lib/
2017-06-01 15:00:39.947 902534 DEBUG cinder.manager
[req-15b9009c-
Schedulers of capabilities ... _publish_
/usr/lib/
~~~
Every 4 seconds!
+++++++
The result is that this is run at the max(spacing,
in most cases (I can't explain the 5 spacing, 3 periodic_interval case
yet), meaning that with the defaults set, this will run every 60
seconds and we can only force this to run at longer intervals than 60
seconds, not at shorter intervals.
Which isn't at all what the description of periodic_interval is saying.
The solution, as suggested by a friend:
@periodic_
Alternatively, this also seems to work
@periodic_
Changed in manila: | |
status: | New → Opinion |
Changed in cinder: | |
assignee: | nobody → Sean McGinnis (sean-mcginnis) |
status: | Triaged → In Progress |
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 ...
: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: