Seite 1 von 1

[CherryPy] Problem mit threads

Verfasst: Sonntag 12. August 2007, 16:43
von EnTeQuAk
Hallo alle zusammen.

Ich bin gerade dabei meine Applikation etwas an CherryPy anzupassen. Nach einem eigenen Request Dispatcher kommt nun eine ordentliche API dran.

Da kommt mir das CherryPy objekt `thread_data` gerade recht.
In diesem kann ich Thread interne Daten zwischen meinen Modulen einfach austauschen.
(es ist ein Objekt, das von `threading._local` erstellt wurde)

Aber ich habe ein paar Probleme mit der Implementation.

Mein code sieht erstmal so aus:

Code: Alles auswählen

#-*- coding: utf-8 -*-
"""
    Our public API to access thread internal
    data from cherrypy or our own thread_data
    thread.

    Internal this module shouldn't be used because we try
    to attach every needed module to the request
    object.
"""
import new, sys

import wwws

from cherrypy import thread_data
from cherrypy import request, response, tools

apis = {}

# it's better to work with only one object
for obj in (request, response, request.app,
            request.dispatch, tools.sessions):
    if obj:
        if hasattr(obj, '__attrname__'):
            # ThreadLocalProxy
            apis[obj.__attrname__] = obj
            continue
        apis[obj.__class__.__name__] = obj
thread_data.__dict__.update(apis)

def to_api(func):
    apis[func.__name__] = func
    func.is_api = True
    return func


#### ***** Our APIs ***** ######

# template environment
from jinja import Environment
from jinja.loaders import FileSystemLoader

thread_data.template_env = Environment(loader=FileSystemLoader(
    searchpath='./templates',
    use_memcache=False, #:XXX: enable it in production mode
    cache_folder=None, #:XXX: enable it in production mode
    auto_reload=True, #:XXX: disable it in production mode
    cache_salt='wwws_webshox'
))

@to_api
def get_app():
    return getattr(thread_data, 'app', None)

@to_api
def get_active_session():
    return getattr(thread_data, 'session', None)

@to_api
def url_for(endpoint, _external=False, **args):
    return thread_data.dispatch.url_map.build(endpoint, args, _external)

@to_api
def render_template(template_name, **context):
    """Renders a template."""
    tmpl = thread_data.template_env.get_template(template_name)
    return tmpl.render(context)


__all__ = list(x for x in locals() if x in apis)
So weit so gut. Das Importieren etc. funktioniert wunderbar. Aber rufe ich nun von einem meiner Module z.B. `render_template` auf, so greift `render_template` nicht auf das vorher definierte Objekt `thread_data` zu sondern erhält ein komplett leeres Objekt ohne die vorher angedockten Objekte.

Hat jemand eine Ahnung, warum?

MfG EnTeQuAk