I was trying to debug a multi-thead issue. In order to reproduce it, I wrote a multi-thread testing in tests.py, but got exception in get_renderer('xxxx.pt'). After some digging, it turns out get_renderer will eventually call get_current_registry, which is thread local. So, I came out with this hack:
<pre> import pyramid.threadlocal from threading import Thread, Lock
pyramid_thread_locals = pyramid.threadlocal.manager.get() threads = [Thread(target=random_func, args=(pyramid_thread_locals, ),) for i in range(100)] for thread in threads: thread.start() for thread in threads: thread.join() </pre>
There is no guarantee that pyramid.threadlocal.manager will always be there. Even if it's there, there's no guarantee it can be used this way. So, this should only be considered as a temporary workaround.
> I was trying to debug a multi-thead issue. In order to reproduce it, I
> wrote a multi-thread testing in tests.py, but got exception in
> get_renderer('xxxx.pt'). After some digging, it turns out get_renderer
> will eventually call get_current_registry, which is thread local. So, I
> came out with this hack:
> pyramid_thread_locals = pyramid.threadlocal.manager.get()
> threads = [Thread(target=random_func, args=(pyramid_thread_locals, ),)
> for i in range(100)]
> for thread in threads:
> thread.start()
> for thread in threads:
> thread.join()
> </pre>
> There is no guarantee that pyramid.threadlocal.manager will always be
> there. Even if it's there, there's no guarantee it can be used this way.
> So, this should only be considered as a temporary workaround.
> Question: is there a better way to do this?
Is there a better way to do what? What problem are you trying to solve? Is the above code a bug report?
On Thu, Aug 30, 2012 at 4:42 PM, Chris McDonough <chr...@plope.com> wrote:
> On 08/30/2012 02:32 AM, John Lee wrote:
>> Dear all,
>> I was trying to debug a multi-thead issue. In order to reproduce it, I
>> wrote a multi-thread testing in tests.py, but got exception in
>> get_renderer('xxxx.pt'). After some digging, it turns out get_renderer
>> will eventually call get_current_registry, which is thread local. So, I
>> came out with this hack:
>> pyramid_thread_locals = pyramid.threadlocal.manager.get()
>> threads = [Thread(target=random_func, args=(pyramid_thread_locals, ),)
>> for i in range(100)]
>> for thread in threads:
>> thread.start()
>> for thread in threads:
>> thread.join()
>> </pre>
>> There is no guarantee that pyramid.threadlocal.manager will always be
>> there. Even if it's there, there's no guarantee it can be used this way.
>> So, this should only be considered as a temporary workaround.
>> Question: is there a better way to do this?
> Is there a better way to do what? What problem are you trying to solve? Is
> the above code a bug report?
No, it's not a bug report. It's a workaround to a problem I
encountered, and I was asking if there's is a better solution.
Like I said, the problem is that if someone write multi-thread testing
without the pyramid.threadlocal.manager hack I showed in the code
above, the newly created thread will have issues when it calls
get_current_registry, because request and registry are thread local.
BTW, each unit test (self._test1 ~ 3) should create its own request
and context (in case of traversal) to avoid racing conditions.