Preserving state in mod_wsgi Flask application

后端 未结 2 1583
余生分开走
余生分开走 2021-01-16 16:38

I have a Flask application running under mod_wsgi that makes a connection to a database. There are multiple processes running this application (only one thread per process)

相关标签:
2条回答
  • 2021-01-16 17:07

    Regarding sharing state between wsgi threads, there is a directive you can put in the apache virtual host configuration that allows them to be executed in the same context.

    The WSGIApplicationGroup directive can be used to specify which application group a WSGI application or set of WSGI applications belongs to. All WSGI applications within the same application group will execute within the context of the same Python sub interpreter of the process handling the request.

    Note that this is for threads within a process, not between processes.

    0 讨论(0)
  • 2021-01-16 17:09

    This I suppose will depend on the database (and ORM) you're using with. If you're using SQLAlchemy or flask-sqlalchemy, (which I highly suggest you to do), you will usually define a single global variable for the database connection. This is usually set up in an init_app()-function. If you look at the application set up code, you'll see that quite often the main flask application object is a global variable app. Very often you'll find the database object as a global variable db which is often imported together with the app to other parts of the application.

    You should look at the application and request-context documentation and especially the locality of the context, which explains how this works. Basically the context is never shared between requests (and thus threads), so there should be no race conditions and no problems.

    Also, the global keyword in your case is not necessary. The point is that you will never really change the content of the variable db. It's an object which controls the database connection and you only call the methods it offers. The global keyword is necessary when you want to mutate the contents of the variable, by assigning a new value to it.

    So, I would refactor the setup() as follows (and preferrably put this an __init__.py so it's nicely importable)

    from flask import Flask
    
    def setup():
        app = Flask(__name__)
        db = get_db() #This is a local variable now
        # whatever else needs to be done
        return app, db
    
    app, db = setup()
    

    And then in the mod_wsgi.py

    from myapp import app
    
    def application(environ, start_response):
        return app(environ, start_response)   
    
    0 讨论(0)
提交回复
热议问题