Skip to content

Latest commit

 

History

History
127 lines (83 loc) · 3.92 KB

FAQ.rst

File metadata and controls

127 lines (83 loc) · 3.92 KB

FAQ

Frequently asked questions on the usage of schedule.

How to execute jobs in parallel?

I am trying to execute 50 items every 10 seconds, but from the my logs it says it executes every item in 10 second schedule serially, is there a work around?

By default, schedule executes all jobs serially. The reasoning behind this is that it would be difficult to find a model for parallel execution that makes everyone happy.

You can work around this restriction by running each of the jobs in its own thread:

import threading
import time
import schedule


def job():
    print("I'm running on thread %s" % threading.current_thread())


def run_threaded(job_func):
    job_thread = threading.Thread(target=job_func)
    job_thread.start()


schedule.every(10).seconds.do(run_threaded, job)
schedule.every(10).seconds.do(run_threaded, job)
schedule.every(10).seconds.do(run_threaded, job)
schedule.every(10).seconds.do(run_threaded, job)
schedule.every(10).seconds.do(run_threaded, job)


while 1:
    schedule.run_pending()
    time.sleep(1)

If you want tighter control on the number of threads use a shared jobqueue and one or more worker threads:

import Queue
import time
import threading
import schedule


def job():
    print("I'm working")


def worker_main():
    while 1:
        job_func = jobqueue.get()
        job_func()

jobqueue = Queue.Queue()

schedule.every(10).seconds.do(jobqueue.put, job)
schedule.every(10).seconds.do(jobqueue.put, job)
schedule.every(10).seconds.do(jobqueue.put, job)
schedule.every(10).seconds.do(jobqueue.put, job)
schedule.every(10).seconds.do(jobqueue.put, job)

worker_thread = threading.Thread(target=worker_main)
worker_thread.start()

while 1:
    schedule.run_pending()
    time.sleep(1)

This model also makes sense for a distributed application where the workers are separate processes that receive jobs from a distributed work queue. I like using beanstalkd with the beanstalkc Python library.

How to continuously run the scheduler without blocking the main thread?

Run the scheduler in a separate thread. Mrwhick wrote up a nice solution in to this problem here (look for run_continuously())

Does schedule support timezones?

Vanilla schedule doesn't support timezones at the moment. If you need this functionality please check out @imiric's work here. He added timezone support to schedule using python-dateutil.

What if my task throws an exception?

Schedule doesn't catch exceptions that happen during job execution. Therefore any exceptions thrown during job execution will bubble up and interrupt schedule's run_xyz function.

If you want to guard against exceptions you can wrap your job function in a decorator like this:

import functools

def catch_exceptions(job_func):
    @functools.wraps(job_func)
    def wrapper(*args, **kwargs):
        try:
            job_func(*args, **kwargs)
        except:
            import traceback
            print(traceback.format_exc())
    return wrapper

@catch_exceptions
def bad_task():
    return 1 / 0

scheduler.every(5).minutes.do(bad_task)

Another option would be to subclass Schedule like @mplewis did in this example.

How can I run a job only once?

def job_that_executes_once():
    # Do some work ...
    return schedule.CancelJob

schedule.today.at('10:30').do(job_that_executes_once)