[CherryPy] Problem mit threads

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

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
Antworten