Can you please email the patch. the indentation is messed up.

On Sep 17, 10:56 am, Jonathan Lundell <[email protected]> wrote:
> On Sep 17, 2010, at 8:24 AM, mdipierro wrote:
>
>
>
> > I will take the patch and you may be fine if your thread does not
> > access db.
>
> Here's a slightly more complete patch. This should maintain backward 
> compatibility with apps that don't use app-specific routing. One that does 
> can call rewrite.select(app='name') at the start of a new thread.
>
> This won't help when globals are based on threading.local, though; that's a 
> nastier problem.
>
> diff -r 3645edf51f22 gluon/rewrite.py
> --- a/gluon/rewrite.py  Fri Sep 17 08:40:21 2010 -0500
> +++ b/gluon/rewrite.py  Fri Sep 17 08:50:17 2010 -0700
> @@ -150,14 +150,15 @@
>      logger.debug('%s: [%s] -> %s (not rewritten)' % (tag, key, default))
>      return (default, query, original_uri)
>
> -def select(e=None):
> +def select(env=None, app=None):
>      """
>      select a set of rewrite params for the current request
>      called from main.wsgibase before any URL rewriting
>      """
> -    app = None
> -    if e and params.routes_app:
> -        (app, q, u) = filter_uri(e, params.routes_app, "routes_app")
> +    if app:
> +        thread.routes = params_apps.get(app, params)
> +    elif env and params.routes_app:
> +        (app, q, u) = filter_uri(env, params.routes_app, "routes_app")
>          thread.routes = params_apps.get(app, params)
>      else:
>          thread.routes = params # default to base rewrite parameters
> @@ -180,6 +181,8 @@
>
>  def filter_out(url, e=None):
>      "called from html.URL to rewrite outgoing URL"
> +    if not hasattr(thread, 'routes'):
> +        select()    # ensure thread.routes is set (for application threads)
>      if thread.routes.routes_out:
>          items = url.split('?', 1)
>          if e:
>
>
>
> > On Sep 17, 10:20 am, Jonathan Lundell <[email protected]> wrote:
> >> On Sep 16, 2010, at 10:44 PM, mdipierro wrote:
>
> >>> Jonathan,
>
> >>> I misunderstood your problem. You should not spawn threads from a
> >>> web2py app. This is not just because the current routing mechanism
> >>> does not support it. This is a very general with all web applications
> >>> because threads are managed by the web server which starts/stops and
> >>> kills them. If your thread spawns a new thread and the parent is
> >>> killed by the web server you may end up with a memory leak.
>
> >>> Please explain what you are trying to achieve, perhaps show us some
> >>> code, and I am sure there is another way.
>
> >> Here's a quick patch to rewrite.filter_out that should fix the problem for 
> >> URL() as long as app-specific routes are not in use:
>
> >>  def filter_out(url, e=None):
> >>      "called from html.URL to rewrite outgoing URL"
> >> +    if not hasattr(thread, 'routes'):
> >> +        select()    # ensure thread.routes is set (for application 
> >> threads)
> >>      if thread.routes.routes_out:
> >>          items = url.split('?', 1)
> >>          if e:
>
> >> Massimo, this will be a little confusing, since there are two Jonathans on 
> >> this (message) thread, and both of us are using application threads.
>
> >> Here's my case:
>
> >> The application is a manager for a collection of servers, from tens to 
> >> possibly hundreds. On the central management page, I create a table that 
> >> summarizes the status of the servers. I get the status by sending an 
> >> xmlrpc query to each server, and the response can take several seconds 
> >> (say 2-10).
>
> >> Because serializing these requests can take too long, I create a thread 
> >> per server to make the query and wait for the response. CPU time for such 
> >> a request is nil, so all the threads complete in approximately the time 
> >> for the slowest one.
>
> >> The code is very simple and very clean.
>
> >> No doubt I could accomplish something like it with Ajax, and effectively a 
> >> request thread for each server. But I hesitate to rely on the web server's 
> >> thread pool, assuming it has one big enough, and an Ajax solution wouldn't 
> >> be so straightforward, I don't think.
>
> >>> Massimo
>
> >>> On Sep 16, 2:26 pm, "Jonathan Z." <[email protected]> wrote:
> >>>> I'm kicking off a threaded process.  As part of the "run" method, I'm
> >>>> calling: env("application", import_models=True) in order to work with
> >>>> the web2py environment inside the context of my thread.  As a result,
> >>>> models are parsed and the following exception is raised:
>
> >>>> Traceback (most recent call last):
> >>>>   File ".../web2py/gluon/restricted.py", line 188, in restricted
> >>>>     exec ccode in environment
> >>>>   File "applications/app/models/db.py", line 32, in <module>
> >>>>     auth = Auth(globals(), db)
> >>>>   File ".../web2py/gluon/tools.py", line 804, in __init__
> >>>>     self.settings.login_url = self.url('user', args='login')
> >>>>   File ".../web2py/gluon/tools.py", line 762, in url
> >>>>     f=f, args=args, vars=vars)
> >>>>   File ".../web2py/gluon/html.py", line 228, in _URL
> >>>>     return URL(*args, **kwargs)
> >>>>   File ".../web2py/gluon/html.py", line 206, in URL
> >>>>     return XML(rewrite.filter_out(url, env))
> >>>>   File ".../web2py/gluon/rewrite.py", line 183, in filter_out
> >>>>     if thread.routes.routes_out:
> >>>> AttributeError: 'thread._local' object has no attribute 'routes'
>
> >>>> As soon as URLs are parsed during Auth initialization, the thread hits
> >>>> a case where an invalid "routes" attribute is dereferenced within
> >>>> rewrite.py.  My threaded code was working until the following change
> >>>> was rolled into 1.84.x: "moved DAL and routes to thread.local"
>
>

Reply via email to