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:
Zhongyue Luo
2014-02-10 11:15:22 +08:00
committed by Gerrit Code Review
parent e7d21ff311
commit cd8e53c37d
2 changed files with 30 additions and 25 deletions

View File

@@ -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)

View File

@@ -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)