durusmail: quixote-users: Re: Request contexts
Request contexts
2003-12-11
Re: Request contexts
2003-12-11
2003-12-11
2003-12-12
2003-12-12
2003-12-13
2003-12-13
2003-12-16
2003-12-16
2003-12-16
2003-12-16
2003-12-15
Re: Request contexts
2003-12-16
2003-12-16
2003-12-24
2003-12-30
2003-12-31
Re: Request contexts
Matt Goodall
2003-12-16
Dave Kuhlman wrote:

>On Sat, Dec 13, 2003 at 12:23:47AM +0000, Matt Goodall wrote:
>
>[snip]
>
>
>
>>It depends on how you define safe ;-). With SCGI there is only one
>>request being handled by a single process at any time. Access to the
>>context and objects in it is inherently thread-safe (there's only one
>>thread) but trying to use the context to store information that must be
>>consistent across all of the application's SCGI processes will cause you
>>much pain. This is true of any process forking setup.
>>
>>
>>
>>>Am I not understanding the concept?
>>>
>>>In an earlier message Graham said:
>>>
>>>
>>>
>>>
>>>
>>>>For example, one could create a database connection as a context
>>>>object, set it in the publisher, and thus make it available to
>>>>all requests that need it.
>>>>
>>>>
>
>OK.  I'm following this suggestion (Graham's I think).  What I've
>done is to sub-class the Publisher class, and (1) in the
>constructor of my sub-class I create a DB connection and (2) I
>override the Publisher's start_request method so that it stuffs the
>connection into the request object before each request is handled.
>Is this an accepted Quixote-ism?
>
>Here is some simple, sample code:
>
>    class MyPublisher(Publisher):
>        def __init__(self, root_namespace, config=None):
>            Publisher.__init__(self, root_namespace, config)
>            self.dbConnection = PgSQL.connect(CONNECT_ARGS)
>        def __del__(self):
>            self.dbConnection.close()
>        def start_request(self, request):
>            Publisher.start_request(self, request)
>            request.dbConnection = self.dbConnection
>
>
>(Again, trying for a little understanding here and remembering that
>I'm using SCGI ...) This is safe (even if the database connection
>itself is not thread-safe) because there is exactly one Publisher
>instance in each process and there is only one request handler
>active concurrently in a single process at any time.  In other
>words, each process is single threaded, as Matt says above.)
>Further more, each request is handled from beginning to end, before
>another request is started in that process (though another request
>may be concurrently handled in other process).  Have I got that
>right?
>
>
I can't comment on overriding Publisher (I don't know Quixote at all
yet) but your description of the threadedness and how requests are
handled is correct.

>And, my clean-up code works, too.  The __del__ method in MyPublisher
>(my subclass of Publisher) is called whenever I restart or stop the
>SCGI server.  Cool.
>
>
Hmm, I wouldn't rely on __del__ methods to clean up resources. For a
start, it's up to the garbage collector when they get called but more
importantly , there's no guarantee that __del__ actually *will* get
called. I understand __del__ can also cause problems in circular
dependencies but I can't remember what the problem is now.

You're better off writing an explicit cleanup() method (or whatever you
want to call it) that is called before the publisher goes out of scope.

>
>
>>>>
>>>>
>>>>
>>>>
>>>But, wouldn't there need to be protection (some kind of lock) so
>>>that only one request used the database connection at a time?  And,
>>>of course, the next step would be to implement a connection pool
>>>that could be shared, would allow check out and check in of
>>>connections, etc.
>>>
>>>
>
>And, across processes a lock would do no good anyway, right?
>
>
Yep, a lock across processes to protect objects in memory is pointless.
However, you should protect updates to things like shared files (you can
use file locks for that particular example). Databases, of course,
implement locking on your behalf.

>
>
>>>
>>>
>>>
>>>
>>Assuming we're still talking SCGI here ...
>>
>>Database connection use only needs to be synchronised in multithreaded
>>applications and, even then, some of the DB-API drivers are already
>>thread safe (when used correctly). Also, there is no point in using
>>connection pools with SCGI as each process only ever needs one
>>connection at most.
>>
>>
>
>Right.  I was focusing on the solution before I really understood
>the problem.  I could not get connection pools out of my head.  It
>was more solution than I needed, I think.
>
>Thanks.
>
>Dave
>
>
>


--
Matt Goodall, Pollenation Internet Ltd
w: http://www.pollenation.net
e: matt@pollenation.net
t: +44 (0)113 2252500




reply