On Dec 12, 2006, at 2:32 PM, Mike Orr wrote:

> 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.
>

The Globals object is global to your entire application. Pylons  
creates one instance of it at startup and your application will see  
that same Globals object as pylons.g in every thread. Your single  
connection created in g would be shared among threads (not thread safe!)

The thread safety in this case ensures a separate Pylons app deployed  
under the same container/process would see its own Globals object  
instead of your first apps' as pylons.g when concurrently serving a  
request in a separate thread.

If you want to recycle the connections in between different requests  
you'll need a connection pool.


> ---------- 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

--
Philip Jenvey


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

Reply via email to