Problem

The simple usage shown in the Quickstart works fine when your deployed application uses a single process (a single app instance). However, chances are you are using something like uWSGI, and your application is served using several processes/workers.

If this is the case, when one of the workers (app instances) updates its configuration values, the rest of the workers will still have their old configuration values. If these old values are then updated, your application workers will have inconsistent configuration variables all the way.

Solution (kind of)

In version 0.2.0, Flask-WaffleConf introduced support for multiprocess deployments by allowing these processes to listen and notify other processes through a Redis channel.

While this means that you need to have Redis installed and running if you intend to use this feature, it also means that workers will update their configuration when another worker notifies them of an update in the values.

Currently, this can be done in two different ways:

  • Using the threading module: the extension creates a thread for each application instance that will listen to the Redis channel and fetch the configuration from the database when notified.

  • Using the gevent module that employs coroutines and greenlet for the same task.

While the first option is the simplest one, it also means that the application will be under the influence of the GIL. This should not be much of an issue due to the listener blocking until a new message is received, it may affect the performance of the application.

The second option should offer better performance because there is no need to use the GIL, but may be more complex to configure depending on the application server used.

Setup for multiprocess use

First, you will need to install the redis and the redis-py module. For Debian systems, this would be done like this:

# apt-get install redis-server

$ pip install redis

Now we need to set additional configuration variables in the application configuration:

# Enable multiprocess use
WAFFLE_MULTIPROC = True

# Redis host (defaults to 'localhost')
WAFFLE_REDIS_HOST = 'MY_HOST'

# Redis port (defaults to 6379)
WAFFLE_REDIS_PORT = 6379

# The channel to listen and send signals to (defaults to 'waffleconf')
WAFFLE_REDIS_CHANNEL = 'MY_CHANNEL'

Once the extension is initialized, the listener will be automatically created.

Using threading

The threading module is used automatically if the gevent module is not present.

You should check your server's documentation to see if you need to modify any configuration in order to use threads in your application. For uWSGI, you would need to use the --enable-threads option and use the --lazy-apps mode for your application, due to the threads not working as intended in the prefork model. For more information on this, check the uWSGI documentation.

Using gevent

If the gevent module is installed, it will be imported first and use monkey patching in order to use greenlets instead of threads.

For uWSGI, you would need to enable gevent support as shown in the documentation.