#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 django-updates+unsubscr...@googlegroups.com.
To post to this group, send email to django-updates@googlegroups.com.
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