Use timestamp in periodic tasks
All time related data in periodic tasks are in seconds. Therefore creating datetime objects only adds overhead to the module. This patch replaces all datetime objects with utc timestamps in periodic_tasks. Changes to test scripts were made accordingly. Change-Id: I5bf77fba26aac62856fe30585577b7cf66dd6257
This commit is contained in:
committed by
Gerrit Code Review
parent
e7d21ff311
commit
cd8e53c37d
@@ -11,7 +11,6 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import datetime
|
||||
import time
|
||||
|
||||
from oslo.config import cfg
|
||||
@@ -19,7 +18,6 @@ import six
|
||||
|
||||
from openstack.common.gettextutils import _
|
||||
from openstack.common import log as logging
|
||||
from openstack.common import timeutils
|
||||
|
||||
|
||||
periodic_opts = [
|
||||
@@ -78,7 +76,7 @@ def periodic_task(*args, **kwargs):
|
||||
if f._periodic_immediate:
|
||||
f._periodic_last_run = None
|
||||
else:
|
||||
f._periodic_last_run = timeutils.utcnow()
|
||||
f._periodic_last_run = time.time()
|
||||
return f
|
||||
|
||||
# NOTE(sirp): The `if` is necessary to allow the decorator to be used with
|
||||
@@ -157,15 +155,15 @@ class PeriodicTasks(object):
|
||||
for task_name, task in self._periodic_tasks:
|
||||
full_task_name = '.'.join([self.__class__.__name__, task_name])
|
||||
|
||||
now = timeutils.utcnow()
|
||||
spacing = self._periodic_spacing[task_name]
|
||||
last_run = self._periodic_last_run[task_name]
|
||||
|
||||
# If a periodic task is _nearly_ due, then we'll run it early
|
||||
if spacing is not None and last_run is not None:
|
||||
due = last_run + datetime.timedelta(seconds=spacing)
|
||||
if not timeutils.is_soon(due, 0.2):
|
||||
idle_for = min(idle_for, timeutils.delta_seconds(now, due))
|
||||
due = last_run + spacing
|
||||
now = time.time()
|
||||
if due > now + 0.2:
|
||||
idle_for = min(idle_for, due - now)
|
||||
continue
|
||||
|
||||
if spacing is not None:
|
||||
@@ -173,7 +171,7 @@ class PeriodicTasks(object):
|
||||
|
||||
LOG.debug(_("Running periodic task %(full_task_name)s"),
|
||||
{"full_task_name": full_task_name})
|
||||
self._periodic_last_run[task_name] = timeutils.utcnow()
|
||||
self._periodic_last_run[task_name] = time.time()
|
||||
|
||||
try:
|
||||
task(self, context)
|
||||
|
||||
@@ -18,12 +18,11 @@
|
||||
Unit Tests for periodic_task decorator and PeriodicTasks class.
|
||||
"""
|
||||
|
||||
import datetime
|
||||
import mock
|
||||
|
||||
from openstack.common.fixture import config
|
||||
from openstack.common import periodic_task
|
||||
from openstack.common import test
|
||||
from openstack.common import timeutils
|
||||
from testtools import matchers
|
||||
|
||||
|
||||
@@ -110,7 +109,6 @@ class ManagerTestCase(test.BaseTestCase):
|
||||
def setUp(self):
|
||||
super(ManagerTestCase, self).setUp()
|
||||
self.config = self.useFixture(config.Config()).config
|
||||
self.addCleanup(timeutils.clear_time_override)
|
||||
|
||||
def test_periodic_tasks_with_idle(self):
|
||||
class Manager(periodic_task.PeriodicTasks):
|
||||
@@ -138,9 +136,10 @@ class ManagerTestCase(test.BaseTestCase):
|
||||
idle = m.run_periodic_tasks(None)
|
||||
self.assertAlmostEqual(60, idle, 1)
|
||||
|
||||
def test_periodic_tasks_idle_calculation(self):
|
||||
fake_time = datetime.datetime(3000, 1, 1)
|
||||
timeutils.set_time_override(fake_time)
|
||||
@mock.patch('time.time')
|
||||
def test_periodic_tasks_idle_calculation(self, mock_time):
|
||||
fake_time = 32503680000.0
|
||||
mock_time.return_value = fake_time
|
||||
|
||||
class Manager(periodic_task.PeriodicTasks):
|
||||
|
||||
@@ -160,22 +159,30 @@ class ManagerTestCase(test.BaseTestCase):
|
||||
self.assertEqual(True, task._periodic_enabled)
|
||||
self.assertEqual(False, task._periodic_external_ok)
|
||||
self.assertEqual(False, task._periodic_immediate)
|
||||
self.assertIsNotNone(task._periodic_last_run)
|
||||
self.assertAlmostEqual(32503680000.0,
|
||||
task._periodic_last_run)
|
||||
|
||||
# Test the manager's representation of those values
|
||||
self.assertEqual(10, m._periodic_spacing[task_name])
|
||||
self.assertIsNotNone(m._periodic_last_run[task_name])
|
||||
self.assertAlmostEqual(32503680000.0,
|
||||
m._periodic_last_run[task_name])
|
||||
|
||||
timeutils.advance_time_delta(datetime.timedelta(seconds=5))
|
||||
m.run_periodic_tasks(None)
|
||||
mock_time.return_value = fake_time + 5
|
||||
idle = m.run_periodic_tasks(None)
|
||||
self.assertAlmostEqual(5, idle, 1)
|
||||
self.assertAlmostEqual(32503680000.0,
|
||||
m._periodic_last_run[task_name])
|
||||
|
||||
timeutils.advance_time_delta(datetime.timedelta(seconds=5))
|
||||
mock_time.return_value = fake_time + 10
|
||||
idle = m.run_periodic_tasks(None)
|
||||
self.assertAlmostEqual(10, idle, 1)
|
||||
self.assertAlmostEqual(32503680010.0,
|
||||
m._periodic_last_run[task_name])
|
||||
|
||||
def test_periodic_tasks_immediate_runs_now(self):
|
||||
fake_time = datetime.datetime(3000, 1, 1)
|
||||
timeutils.set_time_override(fake_time)
|
||||
@mock.patch('time.time')
|
||||
def test_periodic_tasks_immediate_runs_now(self, mock_time):
|
||||
fake_time = 32503680000.0
|
||||
mock_time.return_value = fake_time
|
||||
|
||||
class Manager(periodic_task.PeriodicTasks):
|
||||
|
||||
@@ -202,11 +209,11 @@ class ManagerTestCase(test.BaseTestCase):
|
||||
self.assertIsNone(m._periodic_last_run[task_name])
|
||||
|
||||
idle = m.run_periodic_tasks(None)
|
||||
self.assertEqual(datetime.datetime(3000, 1, 1, 0, 0),
|
||||
m._periodic_last_run[task_name])
|
||||
self.assertAlmostEqual(32503680000.0,
|
||||
m._periodic_last_run[task_name])
|
||||
self.assertAlmostEqual(10, idle, 1)
|
||||
|
||||
timeutils.advance_time_delta(datetime.timedelta(seconds=5))
|
||||
mock_time.return_value = fake_time + 5
|
||||
idle = m.run_periodic_tasks(None)
|
||||
self.assertAlmostEqual(5, idle, 1)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user