APScheduler how to trigger job now
Asked Answered
B

4

13

I have an APScheduler in a Flask app, sending events at some intervals.

Now i need to "refresh" all jobs, in fact just starting them now if they don't run without touching on the defined interval.

I'v tried to call job.pause() then job.resume() and nothing, and using job. reschedule_job(...) would trigger it but also change the interval... which i don't want.

My actual code is bellow:

cron = GeventScheduler(daemon=True)
# Explicitly kick off the background thread
cron.start()

cron.add_job(_job_time, 'interval', seconds=5, id='_job_time')
cron.add_job(_job_forecast, 'interval', hours=1, id='_job_forecast_01')

@app.route("/refresh")
def refresh():
    refreshed = []
    for job in cron.get_jobs():
         job.pause()
         job.resume()
         refreshed.append(job.id)
    return json.dumps( {'number': len(cron.get_jobs()), 'list': refreshed} )
Butz answered 26/8, 2015 at 15:35 Comment(0)
E
-5

You could just run the job function directly too.

for job in cron.get_jobs():
    job.func() 

If you had args or kwargs being passed into the function, you'd have to pull those out of job.args and/or job.kwargs. See apscheduler.job.Job

Encounter answered 30/9, 2015 at 2:20 Comment(0)
T
44

I discourage from calling job.func() as proposed in the accepted answer. The scheduler wouldn't be made aware of the fact that job is running and will mess up with the regular scheduling logic.

Instead use the job's modify() function to set its next_run_time property to now():

for job in scheduler.get_jobs():
    job.modify(next_run_time=datetime.now())

Also refer to the actual implementation of class Job.

Theriot answered 16/8, 2017 at 7:53 Comment(6)
Do you know if changing next_run_time will interfere with the schedule? E.g. if the interval is x will the next run become x in the future from next_run_time when I modify it?Shemeka
If I understand your question and APScheduler correctly, then the job should run at the point in time which you specify with next_run_time (and not a predefined run interval after that point in time)Theriot
Not quite my question. I have jobs I added with a set interval, and I am wondering if the previously planned next run (set by the interval) will be at all affected by modifying the next run time. I assume it will just mean the job won't run again until after interval has passed again?Shemeka
Skimming over APScheduler's source code quickly, it indeed seems to work the way you describe it (scheduler will wait another interval after the manually triggered run). That's a transparent, straight forward approach.Theriot
if the job is pause, this method will run the job immediately but change its status from pause to active.Tedmund
@Tedmund then we could just test whether the job is paused and then skip it, couldn’t we?Theriot
B
5

As a workaround i've done using the following. In summary i cycle through all jobs cron.get_jobs() and create a one-time job using Job object to a 'date' trigger, which only trigger once, at datetime.now since not specified.

def refresh():
    refreshed = []
    for job in cron.get_jobs():
        cron.add_job(job.func, 'date', id='{0}.uniq'.format(job.id), max_instances=1)
        refreshed.append(job.id)
    return json.dumps( {'number': len(cron.get_jobs()), 'list': refreshed} )
Butz answered 27/8, 2015 at 9:8 Comment(1)
Also already 2 years ago, I've posted a new answer that will make user of the proper scheduling mechanisms to start a job now.Theriot
F
1

Very late answer, but I think that what you need is to simply call the methods in your "refresh" route.

Fiance answered 21/11, 2020 at 1:48 Comment(0)
E
-5

You could just run the job function directly too.

for job in cron.get_jobs():
    job.func() 

If you had args or kwargs being passed into the function, you'd have to pull those out of job.args and/or job.kwargs. See apscheduler.job.Job

Encounter answered 30/9, 2015 at 2:20 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.