dbader / dbader/schedule

Running at a specific time weekly calls job twice.

Open
#178 4 comments 1 reaction 0 assignees View on GitHub
Dominant language
Python
Stars
12.3k
Forks
999
PR merge metrics
No merged PRs in 30d

Description

We ran into a minor bug when scheduling `schedule.every().sunday.at("6:00").do(myfunc)` -- `myfunc` is called twice because next run is not updated correctly.

This is clearly difficult to give a test case for unless it happens to be near the time the schedule is set to run for, so we used [freezegun]() to mock `datetime.datetime.now` to increment time in a meaningful way:

```python
import schedule

from freezegun import freeze_time
from unittest.mock import MagicMock
from datetime import datetime, timedelta

def test_schedule_weekly():
mockTask = MagicMock()
m = lambda: mockTask(datetime.now())

start = datetime(2017, 1, 1, 0, 0)
until = datetime(2018, 1, 1, 0, 0)
with freeze_time(start) as fzdt:

scheduler = schedule.Scheduler()
scheduler.every().sunday.at("6:00").do(m)

while datetime.now() < until:
fzdt.tick(delta=timedelta(minutes=15))
scheduler.run_pending()
import pdb; pdb.set_trace()

assert mockTask.call_count == 52 # assert failure 106 != 52
```

This issue could, of course, be due to freezegun, but we should say that updating our code to `scheduler.every().sunday.do(m)` passed the tests. We think it's something to do with `at` and `_schedule_next_run`, which is a bit complicated (RE #116).

We traced out the scheduler.jobs after each call to `run_pending` and found that next run was not updated correctly when the job was run at its given time, but then was updated when the job ran after its scheduled time, here's the trace:

At Sunday, January 1, 2017, 5:45am:

```
>>> scheduler.jobs
[Every 1 week at 06:00:00 do () (last run: [never], next run: 2017-01-01 06:00:00)]
```

At Sunday, January 1, 2017, 6:00am:

```
>>> scheduler.jobs
[Every 1 week at 06:00:00 do () (last run: 2017-01-01 06:00:00, next run: 2017-01-01 06:00:00)]
```

And at Sunday, January 1, 2017, 6:15am:

```
>>> scheduler.jobs
[Every 1 week at 06:00:00 do () (last run: 2017-01-01 06:15:00, next run: 2017-01-08 06:00:00)]
```

We're happy to submit a PR - but it would be useful if someone could point us in the right direction!

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.