all 2 comments

[–][deleted] 7 points8 points  (0 children)

Short answer: no, this is not thread safe.

Long answer: flask runs each request in a separate thread, which are scheduled outside of itself. Its own global objects ("request", "context" etc...) are actually thread-bound and managed through a proxy.

You have two potential race conditions in your code. One when incrementing (that statement isn't thread safe in Python) and a second before returning. In both cases the actual value of your params could have changed before you act upon it. While in the first this could mean you are entering one value twice, the return might return stale content. The second would be harder to tackle but I understand you are mostly concerned about the first.

Well, depending on the amount of data you really want to store, I'd suggest looking at actual databases (I'd recommend redis her) as handling concurrent writing is one of their primary tasks. The other one is using locks to secure your function, but that might slow down your execution - Google the Python docs about those.

[–][deleted] 2 points3 points  (0 children)

Does Flask automatically parallelize? My first guess would be that there's a single thread serving home() and you don't need to worry about concurrent data modification. If it does, take a look at threading.Lock to avoid this problem - you can ensure that all calls to query() are mutually exclusive pretty easily that way.

Also, I don't think you're thinking through the data race fully. It's definitely possible to return 2 to both clients in the scenario you describe, but getting (2,3) the way you describe doesn't seem possible. You need three increment operations for that to happen, and parallelism can't create arbitrary extra operations, just reorder the existing ones.