apscheduler: AndTrigger does not work with IntervalTrigger
Recently, I learn how to use apscheduler, and I find something interesting. From the latest doc’s example, AndTrigger
can be used as:
from apscheduler.triggers.combining import AndTrigger
from apscheduler.triggers.interval import IntervalTrigger
from apscheduler.triggers.cron import CronTrigger
trigger = AndTrigger([IntervalTrigger(hours=2),
CronTrigger(day_of_week='sat,sun')])
scheduler.add_job(job_function, trigger)
Actually, it doesn’t work. I have read https://github.com/agronholm/apscheduler/issues/281 and https://github.com/agronholm/apscheduler/issues/309, and know that the time generated by the two triggers never coincide.
So, if I sepcify a start_date
like
import datetime
from tzlocal import get_localzone
from apscheduler.triggers.combining import AndTrigger
from apscheduler.triggers.interval import IntervalTrigger
tz = get_localzone()
now = datetime.datetime.now(tz=tz)
trigger = AndTrigger([IntervalTrigger(hours=2, start_date=now),
IntervalTrigger(hours=3, start_date=now)])
next_run_time = trigger.get_next_fire_time(None, now + datetime.timedelta(seconds=10))
print(now)
print(next_run_time)
It works as expected.
2019-02-24 22:23:26.052845+09:00
2019-02-25 04:23:26.052845+09:00
But when schedule a job, it does work.
import datetime
from tzlocal import get_localzone
from apscheduler.triggers.combining import AndTrigger
from apscheduler.triggers.interval import IntervalTrigger
from apscheduler.schedulers.blocking import BlockingScheduler
tz = get_localzone()
now = datetime.datetime.now(tz=tz)
def tick():
print('tick')
scheduler = BlockingScheduler()
trigger = AndTrigger([IntervalTrigger(seconds=2, start_date=now),
IntervalTrigger(seconds=3, start_date=now)])
scheduler.add_job(tick, trigger)
scheduler.start()
The real problem it that AndTrigger
may not support IntervalTrigger
In _process_jobs
, it will calculate run times .
In the loop of calculating next_run_time
in AndTrigger
, we only change the value of now
. But in IntervalTrigger
, if we pass previous_fire_time
which is not None
, it will just add the interval. So it caused a dead loop.
Similarly, When we combine IntervalTrigger
and CronTrigger
, if previous_fire_time
is not None
, only CronTrigger
will walk.
About this issue
- Original URL
- State: open
- Created 5 years ago
- Reactions: 1
- Comments: 24 (15 by maintainers)
Something like this is coming to APScheduler 4.0.
I’ve posted issue #465 to track v4.0 development so I will stop posting updates here.
Update: work on AnyIO v2.0 is virtually complete. There are a couple blocker issues I need to take care of before moving on with the release.
Sure - but as far as I’m concerned, just noting this limitation in documentation would be enough. There are ways around it after all.