7

i'm new to python flask REST web services. I'm trying to develop a rest web service which will have a shared queue, multiple threads will constantly write to that queue on the server side and finally when a user calls a GET methods, the service should return first item in the shared queue.

I was trying getting start to develop this by first implementing a shared variable, following is the code I used,

from flask import Flask
app = Flask(__name__)

count= 0 #Shared Variable

@app.route("/")
def counter():
    count = count+1
    return {'count':count}

if __name__ == "__main__":

    app.run() 

But even above code is not working. Then I though of using cache for the shared variable, but it will not the correct way to implement a shared queue (my ultimate goal). Please give me your advises

2 Answers 2

7

The thing you want to do is a little bit more complex than that, I'm afraid.

Flask (and other WSGI python systems) don't work in a single thread - they will normally need to spawn multiple threads and instances to cope with requests coming in without blocking, or without multiple requests accessing the same 'first task' at the same time. Thus global variables don't work as they might in other simple single-threaded python scripts.

You need some way for the different processes to all access the same single queue of data.

Usually, this means outsourcing the data queue to an external database. One popular option is Redis. There's a good intro to flask and redis for exactly this:

http://flask.pocoo.org/snippets/73/

I hope this helps you in the right direction!

Sign up to request clarification or add additional context in comments.

Comments

1

You have a couple of bugs in your example. Here is a version that works:

from flask import Flask, jsonify
app = Flask(__name__)

count= 0 #Shared Variable

@app.route("/")
def counter():
    global count
    count = count+1
    return jsonify({'count':count})

if __name__ == "__main__":
    app.run()

The two problems you have in your version are:

  • You missed to declare count as global in your view function. Without the global declaration the view function creates a local variable of the same name.
  • The response returned by the view function cannot be a dictionary, it needs to be a string or a Response object. I corrected this using jsonify() to convert the dict to a JSON string.

But note that this way of creating a shared value is not robust. In particular note that if you run this application under a web server that creates multiple processes then each process will have its own copy of the count value.

If you need to do this on a production server my recommendation is that you use a database to store your shared value(s).

2 Comments

So is the procedure same, if I want to implement a shared queue (not a integer variable) ?. For now I'm thinking of using a pickle to store the shared queue after every get request, and give access to it through a synchronized block. But if I give the access to queue through a synchronized block, it will not function well with concurrent multiple requests ( every request will have to wait until it get a chance to enter to synchronized block ). what do u think ? (my ultimate goal is to implement a shared queue)
Read my answer again, this is not a good solution. Use a database instead, a lightweight one like Redis would be a good one to use for this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.