From 38cc50bc1e3653eb27d272738c36c889cd27c17d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kupai=20J=C3=B3zsef?= Date: Tue, 20 Nov 2018 19:53:15 +0100 Subject: [PATCH] Eliminating datetime.now() Using utc everywhere to eliminite timezone difference related lurky issues. Change-Id: If90f1404d5a3c26dc2608ba3977199d69879fab7 --- mistral/db/v2/sqlalchemy/api.py | 2 +- mistral/scheduler/default_scheduler.py | 9 +++++---- mistral/services/scheduler.py | 5 +++-- mistral/tests/unit/db/v2/test_sqlalchemy_db_api.py | 8 +++----- mistral/tests/unit/engine/test_task_defaults.py | 4 ++-- mistral/tests/unit/scheduler/test_scheduler.py | 14 ++++++++------ mistral/tests/unit/services/test_scheduler.py | 2 +- 7 files changed, 23 insertions(+), 21 deletions(-) diff --git a/mistral/db/v2/sqlalchemy/api.py b/mistral/db/v2/sqlalchemy/api.py index fcedaee60..da7f80909 100644 --- a/mistral/db/v2/sqlalchemy/api.py +++ b/mistral/db/v2/sqlalchemy/api.py @@ -1183,7 +1183,7 @@ def get_scheduled_jobs_to_start(time, batch_size=None, session=None): # Filter by captured time accounting for a configured captured job timeout. min_captured_at = ( - datetime.datetime.now() - + utils.utc_now_sec() - datetime.timedelta(seconds=CONF.scheduler.captured_job_timeout) ) diff --git a/mistral/scheduler/default_scheduler.py b/mistral/scheduler/default_scheduler.py index 21db17162..0fd6b30e2 100644 --- a/mistral/scheduler/default_scheduler.py +++ b/mistral/scheduler/default_scheduler.py @@ -28,6 +28,7 @@ from mistral.db import utils as db_utils from mistral.db.v2 import api as db_api from mistral import exceptions as exc from mistral.scheduler import base +from mistral import utils LOG = logging.getLogger(__name__) @@ -93,7 +94,7 @@ class DefaultScheduler(base.Scheduler): # Select and capture eligible jobs. with db_api.transaction(): candidate_jobs = db_api.get_scheduled_jobs_to_start( - datetime.datetime.now(), + utils.utc_now_sec(), self._batch_size ) @@ -124,7 +125,7 @@ class DefaultScheduler(base.Scheduler): if context.has_ctx() else {} ) - execute_at = (datetime.datetime.now() + + execute_at = (utils.utc_now_sec() + datetime.timedelta(seconds=job.run_after)) args = job.func_args @@ -201,7 +202,7 @@ class DefaultScheduler(base.Scheduler): """ # Mark this job as captured in order to prevent calling from - # parallel a transaction. We don't use query filter + # a parallel transaction. We don't use query filter # {'captured_at': None} to account for a case when the job needs # to be recaptured after a maximum capture time has elapsed. If this # method was called for job that has non-empty "captured_at" then @@ -209,7 +210,7 @@ class DefaultScheduler(base.Scheduler): # Job Store selected it. _, updated_cnt = db_api.update_scheduled_job( id=scheduled_job.id, - values={'captured_at': datetime.datetime.now()}, + values={'captured_at': utils.utc_now_sec()}, query_filter={'captured_at': scheduled_job.captured_at} ) diff --git a/mistral/services/scheduler.py b/mistral/services/scheduler.py index 1c43e7418..b39a60c07 100644 --- a/mistral/services/scheduler.py +++ b/mistral/services/scheduler.py @@ -29,6 +29,7 @@ from mistral import context from mistral.db import utils as db_utils from mistral.db.v2 import api as db_api from mistral import exceptions as exc +from mistral import utils LOG = logging.getLogger(__name__) @@ -68,7 +69,7 @@ def schedule_call(factory_method_path, target_method_name, if context.has_ctx() else {} ) - execution_time = (datetime.datetime.now() + + execution_time = (utils.utc_now_sec() + datetime.timedelta(seconds=run_after)) if serializers: @@ -180,7 +181,7 @@ class Scheduler(object): """ result = [] - time_filter = datetime.datetime.now() + datetime.timedelta(seconds=1) + time_filter = utils.utc_now_sec() + datetime.timedelta(seconds=1) with db_api.transaction(): candidates = db_api.get_delayed_calls_to_start( diff --git a/mistral/tests/unit/db/v2/test_sqlalchemy_db_api.py b/mistral/tests/unit/db/v2/test_sqlalchemy_db_api.py index 176bb10e8..9692ea85e 100644 --- a/mistral/tests/unit/db/v2/test_sqlalchemy_db_api.py +++ b/mistral/tests/unit/db/v2/test_sqlalchemy_db_api.py @@ -491,7 +491,7 @@ CRON_TRIGGER = { 'workflow_id': None, 'workflow_input': {}, 'next_execution_time': - datetime.datetime.now() + datetime.timedelta(days=1), + utils.utc_now_sec() + datetime.timedelta(days=1), 'remaining_executions': 42, 'scope': 'private', 'project_id': '' @@ -2381,8 +2381,7 @@ CRON_TRIGGERS = [ 'workflow_id': None, 'workflow_input': {}, 'next_execution_time': - utils.drop_microseconds( - datetime.datetime.now() + datetime.timedelta(days=1)), + utils.utc_now_sec() + datetime.timedelta(days=1), 'remaining_executions': 42, 'scope': 'private', 'project_id': '' @@ -2395,8 +2394,7 @@ CRON_TRIGGERS = [ 'workflow_id': None, 'workflow_input': {'param': 'val'}, 'next_execution_time': - utils.drop_microseconds( - datetime.datetime.now() + datetime.timedelta(days=1)), + utils.utc_now_sec() + datetime.timedelta(days=1), 'remaining_executions': 42, 'scope': 'private', 'project_id': '' diff --git a/mistral/tests/unit/engine/test_task_defaults.py b/mistral/tests/unit/engine/test_task_defaults.py index 720d8f1f9..694060e26 100644 --- a/mistral/tests/unit/engine/test_task_defaults.py +++ b/mistral/tests/unit/engine/test_task_defaults.py @@ -185,7 +185,7 @@ class TaskDefaultsReverseWorkflowEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - time_before = dt.datetime.now() + time_before = dt.datetime.utcnow() # Start workflow. wf_ex = self.engine.start_workflow('wf', task_name='task1') @@ -194,7 +194,7 @@ class TaskDefaultsReverseWorkflowEngineTest(base.EngineTestCase): # Workflow must work at least 2 seconds (1+1). self.assertGreater( - (dt.datetime.now() - time_before).total_seconds(), + (dt.datetime.utcnow() - time_before).total_seconds(), 2 ) diff --git a/mistral/tests/unit/scheduler/test_scheduler.py b/mistral/tests/unit/scheduler/test_scheduler.py index 07d591ac5..11f869a78 100644 --- a/mistral/tests/unit/scheduler/test_scheduler.py +++ b/mistral/tests/unit/scheduler/test_scheduler.py @@ -96,7 +96,7 @@ class SchedulerTest(base.DbTestCase): self.assertIsNotNone(captured_at) self.assertTrue( - datetime.datetime.now() - captured_at < + datetime.datetime.utcnow() - captured_at < datetime.timedelta(seconds=3) ) @@ -115,7 +115,7 @@ class SchedulerTest(base.DbTestCase): self.override_config('pickup_job_after', 1, 'scheduler') # 1. Create a scheduled job in Job Store. - execute_at = datetime.datetime.now() + datetime.timedelta(seconds=1) + execute_at = datetime.datetime.utcnow() + datetime.timedelta(seconds=1) db_api.create_scheduled_job({ 'run_after': 1, @@ -146,15 +146,17 @@ class SchedulerTest(base.DbTestCase): # 1. Create a scheduled job in Job Store marked as captured in one # second in the future. It can be captured again only after 3 # seconds after that according to the config option. - captured_at = datetime.datetime.now() + datetime.timedelta(seconds=1) + captured_at = datetime.datetime.utcnow() + datetime.timedelta( + seconds=1 + ) - before_ts = datetime.datetime.now() + before_ts = datetime.datetime.utcnow() db_api.create_scheduled_job({ 'run_after': 1, 'func_name': TARGET_METHOD_PATH, 'func_args': {'name': 'task', 'id': '321'}, - 'execute_at': datetime.datetime.now(), + 'execute_at': datetime.datetime.utcnow(), 'captured_at': captured_at, 'auth_ctx': {} }) @@ -171,6 +173,6 @@ class SchedulerTest(base.DbTestCase): # At least 3 seconds should have passed. self.assertTrue( - datetime.datetime.now() - before_ts >= + datetime.datetime.utcnow() - before_ts >= datetime.timedelta(seconds=3) ) diff --git a/mistral/tests/unit/services/test_scheduler.py b/mistral/tests/unit/services/test_scheduler.py index 0fecc6ec1..250f2459a 100644 --- a/mistral/tests/unit/services/test_scheduler.py +++ b/mistral/tests/unit/services/test_scheduler.py @@ -33,7 +33,7 @@ DELAY = 1.5 def get_time_delay(delay=DELAY * 2): - return datetime.datetime.now() + datetime.timedelta(seconds=delay) + return datetime.datetime.utcnow() + datetime.timedelta(seconds=delay) def target_method():