summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Grönholm <alex.gronholm@nextday.fi>2021-01-10 00:18:24 +0200
committerGitHub <noreply@github.com>2021-01-10 00:18:24 +0200
commit53d0dabd2cb525dfea7a0689745c22a7687f5e2d (patch)
tree3d076a766237774a7a367172cf90e849f708dd2b
parent5add47547331d2b2a8d06cf8ce844f25d47c1b42 (diff)
downloadapscheduler-53d0dabd2cb525dfea7a0689745c22a7687f5e2d.tar.gz
Ensured that jitter is always positive (#416)
Fixes #291.
-rw-r--r--apscheduler/triggers/base.py19
-rw-r--r--docs/versionhistory.rst2
-rw-r--r--tests/test_triggers.py20
3 files changed, 6 insertions, 35 deletions
diff --git a/apscheduler/triggers/base.py b/apscheduler/triggers/base.py
index ce2526a..55d010d 100644
--- a/apscheduler/triggers/base.py
+++ b/apscheduler/triggers/base.py
@@ -22,27 +22,16 @@ class BaseTrigger(six.with_metaclass(ABCMeta)):
def _apply_jitter(self, next_fire_time, jitter, now):
"""
- Randomize ``next_fire_time`` by adding or subtracting a random value (the jitter). If the
- resulting datetime is in the past, returns the initial ``next_fire_time`` without jitter.
-
- ``next_fire_time - jitter <= result <= next_fire_time + jitter``
+ Randomize ``next_fire_time`` by adding a random value (the jitter).
:param datetime.datetime|None next_fire_time: next fire time without jitter applied. If
``None``, returns ``None``.
- :param int|None jitter: maximum number of seconds to add or subtract to
- ``next_fire_time``. If ``None`` or ``0``, returns ``next_fire_time``
+ :param int|None jitter: maximum number of seconds to add to ``next_fire_time``
+ (if ``None`` or ``0``, returns ``next_fire_time``)
:param datetime.datetime now: current datetime
:return datetime.datetime|None: next fire time with a jitter.
"""
if next_fire_time is None or not jitter:
return next_fire_time
- next_fire_time_with_jitter = next_fire_time + timedelta(
- seconds=random.uniform(-jitter, jitter))
-
- if next_fire_time_with_jitter < now:
- # Next fire time with jitter is in the past.
- # Ignore jitter to avoid false misfire.
- return next_fire_time
-
- return next_fire_time_with_jitter
+ return next_fire_time + timedelta(seconds=random.uniform(0, jitter))
diff --git a/docs/versionhistory.rst b/docs/versionhistory.rst
index 623b3e2..7df2888 100644
--- a/docs/versionhistory.rst
+++ b/docs/versionhistory.rst
@@ -12,6 +12,8 @@ APScheduler, see the :doc:`migration section <migration>`.
* Pinned ``tzlocal`` to a version compatible with pytz
* Fixed deprecation warnings on the MongoDB job store and increased the minimum PyMongo
version to 3.0
+* Ensured that jitter is always non-negative to prevent triggers from firing more often than
+ intended
3.6.3
diff --git a/tests/test_triggers.py b/tests/test_triggers.py
index a637485..ea0d1c1 100644
--- a/tests/test_triggers.py
+++ b/tests/test_triggers.py
@@ -50,16 +50,6 @@ class TestJitter(object):
trigger = _DummyTriggerWithJitter(dt, 60)
assert trigger.get_next_fire_time(None, now) == expected_dt
- def test_jitter_in_past_but_initial_date_in_future(self, monkeypatch):
- monkeypatch.setattr(random, 'uniform', lambda a, b: -30.)
-
- now = datetime(2017, 5, 25, 13, 40, 44)
- dt = datetime(2017, 5, 25, 13, 40, 47)
- expected_dt = dt
-
- trigger = _DummyTriggerWithJitter(dt, 60)
- assert trigger.get_next_fire_time(None, now) == expected_dt
-
def test_jitter_in_future_but_initial_date_in_past(self, monkeypatch):
monkeypatch.setattr(random, 'uniform', lambda a, b: 30.)
@@ -70,16 +60,6 @@ class TestJitter(object):
trigger = _DummyTriggerWithJitter(dt, 60)
assert trigger.get_next_fire_time(None, now) == expected_dt
- def test_jitter_misfire(self, monkeypatch):
- monkeypatch.setattr(random, 'uniform', lambda a, b: -30.)
-
- now = datetime(2017, 5, 25, 13, 40, 44)
- dt = datetime(2017, 5, 25, 13, 40, 40)
- expected_dt = dt
-
- trigger = _DummyTriggerWithJitter(dt, 60)
- assert trigger.get_next_fire_time(None, now) == expected_dt
-
def test_jitter_is_now(self, monkeypatch):
monkeypatch.setattr(random, 'uniform', lambda a, b: 4.)