Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Running at a specific time weekly calls job twice. #178

Open
bbengfort opened this issue Nov 20, 2017 · 4 comments
Open

Running at a specific time weekly calls job twice. #178

bbengfort opened this issue Nov 20, 2017 · 4 comments

Comments

@bbengfort
Copy link

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:

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 <lambda>() (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 <lambda>() (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 <lambda>() (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!

@dbader
Copy link
Owner

dbader commented Nov 21, 2017

Thanks for the detailed report @bbengfort, really appreciate it. Unfortunately I don't have the bandwidth right now to further investigate, but if you (or anybody else interested) wants to submit a PR with a fix + a test case to prevent regressions I can make time to review it and prepare a new release.

@dbader
Copy link
Owner

dbader commented Nov 21, 2017

Btw I'm assuming this happens on 0.5.0, is that correct?

@bbengfort
Copy link
Author

@dbader I completely understand about bandwidth; we've switched to every().sunday.do which is working for us, but I think we'll need at eventually. It may not be soon with the holiday season and all, but I'll do my best to take a look at the code and submit a PR.

And yes, it happens on 0.5.0; we observed it on both 0.5.0 and 0.4.3.

@dbader
Copy link
Owner

dbader commented Nov 22, 2017

Sounds good, and again, thanks for the detailed report :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants