Hi.  There's a discussion on the Pylons list about whether it's OK to
put a thread-unsafe database connection in pylons.g, which is a
paste.registry.StackedObjectProxy.  I want to put a Durus connection
there.  My reading of the paste.registry docstring says this is OK.
Could somebody confirm?  Thanks.

---------- Forwarded message ----------
From: Mike Orr <[EMAIL PROTECTED]>
Date: Dec 12, 2006 2:25 PM
Subject: Re: Using Durus with Pylons
To: [email protected]


On 12/12/06, Shannon -jj Behrens <[EMAIL PROTECTED]> wrote:
>
> On 12/11/06, Mike Orr <[EMAIL PROTECTED]> wrote:
[my modified version of...]
> > > > quickwiki.lib.app_globals contains:
> > > >
> > > >     class Globals(object):
> > > >         def __init__(self, global_conf, app_conf, **extra):
> > > >             self.db_connection = get_connection(app_conf)
> > > >
> > > > If the Globals object is thread-specific, I should be safe using
> > > > g.db_connection, right?
> > > >
> > > The globals object is *not* thread-specific!  I suggest you instead
> > > create the connection in lib/base.py within the __call__.
> >
> > Then I'll be creating a connection for every request.  Is there no
> > better place to do it once per thread?
>
> I'm surprised by this question.  Doesn't every request get a new
> thread?  I didn't think the threads were getting reused.

Each thread processes several requests from a shared queue, see
paste.httpserver.ThreadPool.worker_thread_callback().  The object in
the queue is a lambda defined in
paste.httpserver.ThreadPoolMixin.process_request().  The lambda does
all the request processing including sending the response to the
client.  If the queue element is a special SHUTDOWN value, the thread
exits.

So is the globals object really thread-unsafe?  I thought it was a
StackedObjectProxy (in pylons.__init__) precisely for this purpose, so
you can put something like a thread-specific database connection
there.  The docstring for 'paste.registry' says this if I'm reading it
correctly:


[StackedObjectProxy is a ...]
"""Registry for handling request-local module globals sanely

Dealing with module globals in a thread-safe way is good if your
application is the sole responder in a thread, however that approach fails
to properly account for various scenarios that occur with WSGI applications
and middleware.

What is actually needed in the case where a module global is desired that
is always set properly depending on the current request, is a stacked
thread-local object. Such an object is popped or pushed during the request
cycle so that it properly represents the object that should be active for
the current request.

To make it easy to deal with such variables, this module provides a special
StackedObjectProxy class which you can instantiate and attach to your
module where you'd like others to access it. The object you'd like this to
actually "be" during the request is then registered with the
RegistryManager middleware, which ensures that for the scope of the
current WSGI application everything will work properly."""


> If so, and
> if you're worried about the cost of creating new connections, you
> should be using a connection pool; sorry, I know that's a *duh* kind
> of statement ;)

Durus doesn't have a connection pool but I could write one a la
SQLAlchemy if it becomes necessary.  But a thread-local variable would
be a simpler equivalent.  I'm trying to avoid creating my own
StackedObject proxy and registering it and creating a middleware if I
don't have to.

I finally ended up putting the connection in
MyController.__before__().  That way it's created only in controllers
that actually use the database,and it's one less module to modify.
But I still want to see if it's possible to use one connection for
several requests.

--
Mike Orr <[EMAIL PROTECTED]>


-- 
Mike Orr <[EMAIL PROTECTED]>

_______________________________________________
Paste-users mailing list
[email protected]
http://webwareforpython.org/cgi-bin/mailman/listinfo/paste-users

Reply via email to