diff options
author | Alex Grönholm <alex.gronholm@nextday.fi> | 2021-01-10 00:18:24 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-10 00:18:24 +0200 |
commit | 53d0dabd2cb525dfea7a0689745c22a7687f5e2d (patch) | |
tree | 3d076a766237774a7a367172cf90e849f708dd2b | |
parent | 5add47547331d2b2a8d06cf8ce844f25d47c1b42 (diff) | |
download | apscheduler-53d0dabd2cb525dfea7a0689745c22a7687f5e2d.tar.gz |
Ensured that jitter is always positive (#416)
Fixes #291.
-rw-r--r-- | apscheduler/triggers/base.py | 19 | ||||
-rw-r--r-- | docs/versionhistory.rst | 2 | ||||
-rw-r--r-- | tests/test_triggers.py | 20 |
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.) |