1

If I have a RequestHandler class, that has a variable (self.var below) that is initialized during a request. Can that variable be overwritten in a concurrent environment (threadsafe=true)? E.g.

class MyRequestHandler(webapp2.RequestHandler):
    var = None
    def get(self, id):
        self.var = value_from_datastore(id)
        # Do something that takes time
        # ...
        self.response.write.out(self.var)
        self.response.write.out(self.var2)

Can self.var be overwritten by a second request (presumably from a different user) between when it is set at the top of the get method and when it's used in the output?

Thanks,

Baird

Update:

I was under the (mistaken) impression that the var = None was declaring it as an instance variable. Thanks for correcting my (gaping) misconception ;-)

If I do the "declaration" in the __init__, am I better off? I think it comes down to if MyRequestHandler is created for each thread, or if there is only one for all the shared threads. Can there still be interference from different requests by different users?

class MyRequestHandler(webapp2.RequestHandler):
    def __init__(self):
        self.var = None
    def get(self, id):
        self.var = value_from_datastore(id)
        # Do something that takes time
        # ...
        self.response.write.out(self.var)
        self.response.write.out(self.var2)

Thanks,

Baird

Baire
  • 45
  • 9

1 Answers1

2

class variables are not threadsafe in Python. To make class variables threadsafe. See this article from Nick Johnson.

In webapp2 you can use the app registry: http://webapp-improved.appspot.com/guide/app.html#registry. Or if you need a "global" for your reguest (not shared), you can use the request registry.

Update :

class variables vs instance variables:

>>> class A(object):
...     a = 10                          # this is a class variable
...     def testa(self):
...         print A.a
...         print self.a
...     def adda(self, b):
...         self.a = self.a + b     # here we create an instance variable
...         
>>> x = A()
>>> x.testa()
10
10
>>> A.a = 50
>>> x.testa()
50
50
>>> x.adda(7)
>>> x.testa()
50
57
>>> A.a = 15
>>> x.testa()
15
57
voscausa
  • 11,253
  • 2
  • 39
  • 67
  • Thanks voscausa, but do you mean static variables on the class, or instance variables? My example above is an instance variable. I guess it comes down to if the RequestHandler itself is unique per thread or shared over the various threads. – Baire Jan 02 '13 at 16:44
  • I have updated my answer, to show Python working with class variables. I can change the instance, by manipulating the class variable. – voscausa Jan 02 '13 at 17:43
  • I've updated by initial post. I think I get the pure python issue here, but what about Google app engine RequestHandler instances? – Baire Jan 02 '13 at 22:29
  • Now your code is threadsafe, you do not use a "global". Every request has it own thread and maybe they use different instances, which depends on the load. But, see also : http://stackoverflow.com/questions/11525717/when-does-the-app-engine-scheduler-use-a-new-thread-vs-a-new-instance – voscausa Jan 02 '13 at 22:45