Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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} )
like image 253
dashie Avatar asked Aug 26 '15 15:08

dashie


People also ask

How does APScheduler work?

APScheduler provides many different ways to configure the scheduler. You can use a configuration dictionary or you can pass in the options as keyword arguments. You can also instantiate the scheduler first, add jobs and configure the scheduler afterwards. This way you get maximum flexibility for any environment.

What is Max_instances in APScheduler?

The max_instances only tells you how many concurrent jobs you can have. APScheduler has three types of triggers: date interval cron. interval and cron repeat forever, date is a one-shot on a given date.

How do I stop APScheduler?

It only stops when you type Ctrl-C from your keyboard or send SIGINT to the process. This scheduler is intended to be used when APScheduler is the only task running in the process. It blocks all other code from running unless the others are running in separated threads.


2 Answers

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.

like image 67
Lars Blumberg Avatar answered Oct 11 '22 23:10

Lars Blumberg


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} )
like image 24
dashie Avatar answered Oct 12 '22 01:10

dashie