I have one computer connected to multiple instruments. On this computer, there's an nginx
server that serves a Falcon WSGI
application using uWSGI. The application is thought so that if one user requires access to an instrument, this becomes unavailable to others. I achieve this by the following piece of (stripped-down version of my) code:
import json
import falcon
class Lab(object):
def __init__(self):
self.available_instruments = ["money_maker", "unicornifier"] # Not actual instruments
self.connected_instruments = []
def on_get(self, request, response):
response.status = falcon.HTTP_OK
response.content_type = "application/json"
response.body = json.dumps({
"connected": self.connected_instruments,
"available": self.available_instruments
})
def on_post(self, request, response):
json_body = json.loads(request.body)
instrument = json_body['connect']
if instrument in self.connected_instruments:
raise falcon.HTTPBadRequest('Busy')
elif instrument not in self.available_instruments:
raise falcon.HTTPBadRequest('No such instrument')
self.connected_instruments.append(instrument)
response.status = falcon.HTTP_OK
response.content_type = "application/json"
response.body = json.dumps({
"connected": self.connected_instruments,
"available": self.available_instruments
})
application = falcon.API()
l = Lab()
application.add_route('/', lab)
And the request body
{
"connect": "money_maker"
}
When I "connect" an instrument, the immediate answer shows that it is connected. But successive GET requests don't give the expected answer. I get
{
"connected": [],
"available": ["money_maker", "unicornifier"]
}
But this does not happen if I execute the above code on a local uWSGI instance, for testing purposes. Is there any nginx-uWSGI interaction that I'm not aware of? Any amount of help is appreciated.
For the sake of completeness, here follow the nginx.conf
and the api.ini
file called by uWSGI.
#nginx config file for uWSGI requests routing
server {
listen 80;
server_name example.com;
location /api {
include uwsgi_params;
uwsgi_pass unix:///tmp/api.sock;
}
}
api.ini
[uwsgi]
master = true
processes = 5
socket = /tmp/%n.sock
chmod-socket = 666
uid = apidev
gid = www-data
chdir = %d../%n
pythonpath = %d../%n
module = %n
vacuum = true
self.connected_instruments.append(instrument)
just stores the posted data in memory! ie, in the memory space of one process... but when you run 5 uwsgi processes behind nginx then you have a very high chance of posting the data to one process and then being served by another process who does not have that data.
You must use a database or something that all processes can share to save and retrieve data.