Is there a way to run initialization code in each uwsgi worker (after forking)
Asked Answered
P

1

5

Is there a way (in uWSGI or Flask) to register a function to be run in each worker after spawning but as soon as possible?

We have a flask app that benefits from preloading a bunch of stuff. The following only calls preload once for the 8 worker processes. The first request is fast, but the preloaded objects are shared in some fashion that causes errors.

app = Flask(__name__)
preload()

If I use before_first_request, then the objects are loaded in each worker process and there are no errors, but the first request is very slow.

app = Flask(__name__)

@app.before_first_request
def bfr():
    preload()

I also tried setting up a flask script. Running the command works, but obviously the objects are loaded in the command's process rather than the uwsgi workers.

app = Flask(__name__)
manager = Manager(app)

@manager.command
def preload():
    ...

I guess if we use before_first_request, we could manually trigger a request after restarting uwsgi. Is that the only solution here?

edit: Just found the uswgi hook-post-fork option (and other hook options). I'm going to try that tomorrow. Maybe one of those is what I need.

Prickly answered 20/3, 2019 at 18:57 Comment(1)
Are you using celery or some worker for dealing with background tasks?Yancey
P
7

The postfork decorator worked for me, just took a little while to find.

import uwsgidecorators

@uwsgidecorators.postfork
def preload():
    ...
Prickly answered 21/3, 2019 at 15:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.