We are using the following setup: NGINX+Gunicorn+Flask. We need to add just a little bit of caching, no more than 5Mb per Flask worker. SimpleCache seems to be simplest possible solution - it uses memory locally, inside the Python process itself.
Unfortunately, the documentation states the following:
"Simple memory cache for single process environments. This class exists mainly for the development server and is not 100% thread safe."
However, I fail to see where thread safety would matter at all in our setup. I think that Gunicorn keeps several Flask workers running, and each worker has its own small cache. What can possibly go wrong?
Flask itself does not provide caching for you, but Flask-Caching, an extension for Flask does. Flask-Caching supports various backends, and it is even possible to develop your own caching backend.
Simply set your app. config's CACHE_TYPE key to "null" before you initialize Flask-Cache: app. config["CACHE_TYPE"] = "null" # change to "redis" and restart to cache again # some time later cache.
I am currently dealing with a scenario in which after a user logs in the app I want to insert his IP, username into a database.
Now, the way I can do that only once is by using a Cache to store the user`s ip and username in the cache.
Now the problem arises when each gunicorn process initializes its own cache. If add the username+ip combination for proc1's cache if proc2 picks up the next request by the same user it won't find it in its cache and hence add it to its cache and the database again, which is not suitable. Hence, a thread-safe (process-safe) cache is important in this case.
Example logs:
2015-07-07 22:42:31 - myapp.views:29 - DEBUG - not from cache user1100.100.100.100, <type 'unicode'> [14776]
2015-07-07 22:42:31 - myapp.views:30 - DEBUG - from cache : user1100.100.100.100, <type 'unicode'> [14776]
2015-07-07 22:42:40 - myapp.views:29 - DEBUG - not from cache user1100.100.100.100, <type 'unicode'> [14776]
2015-07-07 22:42:40 - myapp.views:30 - DEBUG - from cache : user1100.100.100.100, <type 'unicode'> [14776]
2015-07-07 22:42:41 - myapp.views:29 - DEBUG - not from cache user1100.100.100.100, <type 'unicode'> [14779]
2015-07-07 22:42:41 - myapp.views:30 - DEBUG - from cache : None, <type 'NoneType'> [14779]
2015-07-07 22:42:41 - myapp.views:32 - DEBUG - new username ip [14779]
2015-07-07 22:42:41 - myapp.views:38 - DEBUG - User : user1, ip : 100.100.100.100, noted at time : Tue Jul 7 22:42:41 2015, login_count : None [14779]
You can see gunicorn process 14776 added it to its cache first and the next request was picked by 14776 and hence the database entry happened only once, but after that the next request got picked up by 14779 which add it to its cache and hence the db.
cache = SimpleCache(threshold=1000, default_timeout=3600)
Using a memcache or redis based cache might solve it. I`m experimenting with that myself.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With