apscheduler
apscheduler copied to clipboard
Problem on combining triggers
Hi, I'm trying to use combine triggers. For example, I want to run a function on the first minute for every 2 seconds:
from time import sleep
from apscheduler.triggers.combining import AndTrigger
from apscheduler.triggers.interval import IntervalTrigger
from apscheduler.triggers.cron import CronTrigger
from apscheduler.schedulers.background import BackgroundScheduler
def job_function():
print("hello from function")
if __name__ == "__main__":
scheduler = BackgroundScheduler()
trigger = AndTrigger([IntervalTrigger(seconds=2),
CronTrigger(minute=1)])
scheduler.add_job(job_function, trigger)
print("before start", scheduler.get_jobs())
scheduler.start()
print("after start", scheduler.get_jobs())
print("ok")
while True:
sleep(.1)
But the program never prints after start
. It is very strange to me. The OrTrigger
works fine for this example. If it is a bug is there any workaround?
You're not the first one to run into this issue. This happens because the times generated by the two triggers never coincide because IntervalTrigger
starts from the current time which of course has milliseconds that are unlikely to be exact 0, while CronTrigger
produces datetimes with the fractional part as 0. The question is, how to resolve this? Should CronTrigger
ignore the fractional part when comparing datetimes, or should IntervalTrigger
's start time drop the millisecond part?
Thanks, I tried a method that creates two jobs. first with a cron job
as expected. In the cron job
itself, it creates an interval job
and the job destroyed after a specific amount of runs (I added this by myself manually). Here is my example, I want to run my function on the 10th day of each month on 10:0:0 on every 10 seconds for 6 times. If each call of my function takes less than 10 seconds. on 10:1:0 the interval should end. Is there any way to do this with combining triggers or what I've done is the best I can do?
Why not just: day=10, hour=10, second='*/10'
?
You are right but how about adding a limitation on the amount of function runs like run only for 6 times only, how can I implement that?
The proper solution would have been to use CronTrigger(minute=1, second="*/2")
. v4.0.0a1 also includes a threshold
parameter for AndTrigger
which can be used to solve the issue of the trigger run times not matching exactly.