#26888: RegexURLResolver doesn't work in threaded environments
-------------------------------------------+-------------------------
               Reporter:  MarkusH          |          Owner:  MarkusH
                   Type:  Uncategorized    |         Status:  new
              Component:  Core (URLs)      |        Version:  1.10
               Severity:  Release blocker  |       Keywords:
           Triage Stage:  Accepted         |      Has patch:  0
    Needs documentation:  0                |    Needs tests:  0
Patch needs improvement:  0                |  Easy pickings:  0
                  UI/UX:  0                |
-------------------------------------------+-------------------------
 As reported on [https://groups.google.com/forum/#!topic/django-
 developers/D_bIeinKHjE django-developers]:

 I'm using django (1, 10, 0, u'beta', 1).

 When I try to reverse url in shell everything goes fine.

 When under nginx/uwsgi with many concurrent request I get

 {{{#!python
 ... /local/lib/python2.7/site-packages/django/urls/resolvers.py", line
 241,
 in reverse_dict
     return self._reverse_dict[language_code]
 KeyError: 'it'
 }}}

 After a wile I figured out that RegexURLResolver is memoized by
 `get_resolver` and so it acts like a singleton for a certain number of
 requests.

 Analyzing the code of  RegexURLResolver I found that the method
 `_poupulate` will return directly if it has been called before and not yet
 finished.

 {{{#!python
 ...
 def _populate(self):
     if self._populating:
         return
     self._populating = True
 ...
 }}}

 if used for recursive call in a single thread this will not hurt, but in
 my case in uwsgi multi thread mode I got the error.

 here is my quick and dirty fix:

 {{{#!python
 class RegexURLResolver(LocaleRegexProvider):
     def __init__(self, regex, urlconf_name, default_kwargs=None,
 app_name=None, namespace=None):

         ...

         self._populating = False
         self.RLock = threading.RLock()

         ...

     def _populate(self):
         if self._populating:
             self.RLock.acquire()
             self.RLock.release()
             return
         self._populating = True
         self.RLock.acquire()

         ...

         self._populating = False
         self.RLock.release()
 }}}

--
Ticket URL: <https://code.djangoproject.com/ticket/26888>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/050.be37cb4a04b79a8c21cbd19a074c7b06%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to