Forums

Question on Global variables

Hi, I am experimenting with a Telegram bot application where in one case I need to sequentially send information by increasing one index when the user push a determined button.

So, I've defined a global variable count which I initialize as zero at the beginning of flask_app.py.

The thing is that in a random way and while count is indexing and having any value, upon a POST request , the value goes to zero making the DB search fail. As Telegram keeps sending the POST until having a 200 response, I can see the variable is going back to the expected increased index value. Sometimes, it takes like two or three request.

How can avoid or work around on this?
Does flask_app.py starts from the beginning sometimes ? I understand it must start after the @app.route() function.

 if query:

        chat_id = query.message.chat_id

        bot.sendMessage(chat_id=chat_id, text='<b>Rec Button on count =  </b>' + str(count) , parse_mode=telegram.ParseMode.HTML)
        ss = "SELECT Stat FROM RIGS WHERE ID = " + str(count)
        c.execute(ss)
        all_rows = c.fetchall()
        n = all_rows[0]

        statt = n[0]

        if query.data == '1':
            data = 'DOSOK'

        elif query.data == '2':
            data = 'CHECK'

        elif query.data == '3':
            data = 'NOLOG'


        elif query.data == '4':
            data = statt


        update_query = " UPDATE RIGS SET Stat = " + "'" + data + "'" +  "WHERE ID = " + "'"+ str(count) + "'"
        #update_query = " UPDATE RIGS SET Stat = " + data +  "WHERE ID = " + "'" + str(count) + "'"
        c.execute(update_query)
        conn.commit()
        count = count + 1
        if count == 36:
            count =1
        #conn.commit()
        Select_info(count, chat_id, reply_markup)

count is initialized as zero at the beginning and defined as global in the app as shown on below partial code.

@app.route('/', methods=['POST'])
def webhook_handler():
global count
global SM

if request.method == "POST":

Thanks a million for any help!

Rgds..... Jose

What you are describing may be because of the fact that you may have more than one web worker. Each worker is a separate process, hence the count for each worker might be different/zero even after you have increased the count for another worker.

Thanks, yes , because another tests I did, it does look as if there are two or more threads running together. How can I force to have a single thread ?

As per Google search, it seems to be Flask does spawn multiple threads...

You mentioned "worker" is it possible to have just one?

Thanks in advance !

Yes, workers are separate processes so they'd have the same effect as multiple threads. It is possible to have just one, but that probably wouldn't get you exactly the effect you want; firstly it would reduce the number of hits your app can handle to half its current capacity, and secondly it would still not make the app resilient to restarts -- your web app may be restarted at pretty much any time, as we rebalance load across the PythonAnywhere cluster, at which point your counter would be set to zero again.

It might also be worth mentioning that count in your existing code is not per-user, it's global across the application, so if you had multiple users, you'd have the same count shared between them -- I don't know enough about your use case to know if that's what you want or not.

I see you're already using a database -- could you not just store the count in the DB, either as a one-row, one-column table (if you do want a count global across all users) or in a table mapping from user IDs to counts (if you want one per user)?

Giles, Thanks a lot. Yes, I've just did that exactly, added two fields in the DB to hold for count and another variable and the app is now running OK.

On the other side, just to understand better how flask is working, as per my above code, each time the server receives a POST on my pythonanywhere page, the function below the line @app.route('/', methods=['POST']) will be immediately called and if it is still running and there is another hit, it will start over on another separated thread. Is this how this works?

Thanks a lot for your help!

Excellent, glad we found a solution :-)

You're almost right on how the requests are processed. Your website has a number of worker processes running constantly. When requests come in, they're put on a queue. When worker processes are idle, they take the request at the front of the queue, process it, return a response, and then go back into an idle state. So in normal operation (when you're not getting lots of incoming requests) then requests stay in the queue for almost no time, as there's always a worker process to handle them instantly. But when things are busy, there's can be a lag.