Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Would starting APScheduler in a uwsgi app end up with one scheduler for each worker?

I have a flask application in which I need the scheduling feature of APScheduler. The question is:

Where do I start the scheduler instance?

I use uwsgi+nginx to serve this application with multiple workers, wouldn't I end up with multiple instances of Scheduler that would be oblivious of each other? If this is correct, a single job would be triggered multiple times, wouldn't it?

What is the best strategy in this case so I end up with just one Scheduler instance and still be able to access the application's context from within the scheduled jobs?

This question has the same problem albeit with gunicorn instead of uwsgi, but the answer could be similar.

Below is the code defining "app" as a uwsgi callable application object. The file containing this code is called wsgi.py (not that it matters).

app = create_app(config=ProductionConfig())

def job_listener(event):
    get_ = "msg from job '%s'" % (event.job)
    logging.info(get_)

# This code below never gets invoked when I check with worker_id() == 1
# The only time it is run is with worker_id() value of 0
app.sched = Scheduler()
app.sched.add_jobstore(ShelveJobStore('/tmp/apsched_%d' % uwsgi.worker_id()), 'file')
app.sched.add_listener(job_listener,
                   events.EVENT_JOB_EXECUTED |
                   events.EVENT_JOB_MISSED |
                   events.EVENT_JOB_ERROR)
app.sched.start()
like image 442
Will Avatar asked Jun 22 '14 15:06

Will


2 Answers

uWSGI has a feature called mules (see: http://uwsgi-docs.readthedocs.org/en/latest/Mules.html), you can use them to start a script under the master which is not accessible via socket. It's designed to offload a work from the main app using schedulers and for signal handling so it seems to be perfect for deploying a scheduler inside the uwsgi stack.

like image 85
intense Avatar answered Sep 18 '22 08:09

intense


UWSGI has a function uwsgi.worker_id(). If you start the scheduler conditionally in a specific worker, you won't end up with multiple scheduler instances.

like image 29
Alex Grönholm Avatar answered Sep 18 '22 08:09

Alex Grönholm