I needed a simple test-and-set instruction in my Flask webserver. The code for the TaS is pretty straightforward (I don't think this is the problem actually, but I'm putting it here for completeness):
from threading import Lock
class TaS:
def __init__(self, default):
self.__lock = Lock()
self.__value = default
def update(self, new):
self.__lock.acquire()
old = self.__value
self.__value = new
self.__lock.release()
return old
I made this sample Flask application to check if it works:
from Asdf import app
from ...helpers import TaS
from time import sleep
from flask import jsonify
l = TaS(0)
@app.route("/test")
def test():
old = l.update(1)
sleep(3)
return jsonify({"Old TaS value" : old})
Now, when I run this locally and make 2 requests within 3 seconds, the responses I get are: {"Old TaS value": 0}
and {"Old TaS value": 1}
, so it looks like my TaS works nicely. However, when I push it to an Azure dev server and make two concurrent requests, I get {"Old TaS value": 0}
and {"Old TaS value": 0}
... After the two concurrent requests have finished and I make one or more new requests (concurrent or not, it doesn't matter) I do always get {"Old TaS value": 1}
responses.
What is going on? It looks like Azure only actually executes 1 of multiple identical concurrent requests and then returns its result to all requests. Even when I add random unique get parameters to the urls of the concurrent requests, they all respond with {"Old TaS value": 0}
. It feels like very weird caching I didn't ask for.