Make cron-triggers not play catchup

Currently if the API is stopped for a length and restarted the crontrigger
jobs will have their next execution in the past and will do a catchup
running a lot of times. That happens because the next execution is
calculated based on the first time it was executed. This change makes it be
the next execution time be the max of the calculated time and utcnow so
that if the server is lagging we keep uptodate with the calculated next
execution times.

Change-Id: I05b35261b1adbe17a1b0316eee95da12634c3978
Closes-bug: 1719882
This commit is contained in:
Adriano Petrich 2018-06-06 16:32:09 +01:00
parent 734851fb1f
commit 07c26e50dc
2 changed files with 12 additions and 1 deletions

View File

@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import datetime
import json
from oslo_config import cfg
@ -121,9 +122,11 @@ def advance_cron_trigger(t):
delete_trust=False
)
else: # if remaining execution = None or > 0.
# In case the we are lagging or if the api stopped for some time
# we use the max of the current time or the next scheduled time.
next_time = triggers.get_next_execution_time(
t.pattern,
t.next_execution_time
max(datetime.datetime.utcnow(), t.next_execution_time)
)
# Update the cron trigger with next execution details

View File

@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import datetime
import time
import mock
from oslo_config import cfg
@ -120,7 +121,9 @@ class ProcessCronTriggerTest(base.EngineTestCase):
next_trigger = next_triggers[0]
next_execution_time_before = next_trigger.next_execution_time
ts_before = datetime.datetime.utcnow()
time.sleep(1) # this is to simulate lagging
periodic.process_cron_triggers_v2(None, None)
next_triggers = triggers.get_next_cron_triggers()
@ -130,6 +133,11 @@ class ProcessCronTriggerTest(base.EngineTestCase):
next_trigger = next_triggers[0]
next_execution_time_after = next_trigger.next_execution_time
self.assertGreater(
next_execution_time_after,
ts_before
)
self.assertNotEqual(
next_execution_time_before,
next_execution_time_after