Context/Thread-Locals vs. Explicit Argument Passing¶
In any pecan application, the module-level pecan.request
and
pecan.response
are proxy objects that always refer to the request and
response being handled in the current thread.
This thread locality ensures that you can safely access a global reference to the current request and response in a multi-threaded environment without constantly having to pass object references around in your code; it’s a feature of pecan that makes writing traditional web applications easier and less verbose.
Some people feel thread-locals are too implicit or magical, and that explicit
reference passing is much clearer and more maintainable in the long run.
Additionally, the default implementation provided by pecan uses
threading.local()
to associate these context-local proxy objects with the
thread identifier of the current server thread. In asynchronous server
models - where lots of tasks run for short amounts of time on
a single shared thread - supporting this mechanism involves monkeypatching
threading.local()
to behave in a greenlet-local manner.
Disabling Thread-Local Proxies¶
If you’re certain that you do not want to utilize context/thread-locals in
your project, you can do so by passing the argument
use_context_locals=False
in your application’s configuration file:
app = {
'root': 'project.controllers.root.RootController',
'modules': ['project'],
'static_root': '%(confdir)s/public',
'template_path': '%(confdir)s/project/templates',
'debug': True,
'use_context_locals': False
}
Additionally, you’ll need to update all of your pecan controllers to accept positional arguments for the current request and response:
class RootController(object):
@pecan.expose('json')
def index(self, req, resp):
return dict(method=req.method) # path: /
@pecan.expose()
def greet(self, req, resp, name):
return name # path: /greet/joe
It is imperative that the request and response arguments come after
self
and before any positional form arguments.