dashie
dashie

Reputation: 323

APScheduler how to trigger job now

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} )

Upvotes: 14

Views: 26610

Answers (4)

Lars Blumberg
Lars Blumberg

Reputation: 21461

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.

Upvotes: 49

Daniel Bernal
Daniel Bernal

Reputation: 334

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

Upvotes: 1

Everett Toews
Everett Toews

Reputation: 10974

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

Upvotes: -5

dashie
dashie

Reputation: 323

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} )

Upvotes: 5

Related Questions