
Hi,
I'm playing with Django (1.1.1) under Twisted Web (9.0.0) through the WSGI interface. When using my web app under the test server with sqlite3 as the DBMS, I'm having troubles since in-memory sqlite3 DBs can't be shared among threads.
The solution I came up with was to run the WSGIResource in the main thread. In order to do so, I subclassed the WSGIResource as follows:
----- from twisted.web.wsgi import WSGIResource,_WSGIResponse from twisted.web.server import NOT_DONE_YET
class MainThreadWSGIResource(WSGIResource): def __init__(self,reactor,app): WSGIResource.__init__(self,reactor,None,app)
def render(self,request): response = _WSGIResponse( self._reactor, self._threadpool, self._application, request) response.run() return NOT_DONE_YET -----
Basically, I replaced "response.start()" in the original render() method with the "response.run()", bypassing the callInThread() call in the _WSGIResponse's start() method. Even if it works, I hate importing _WSGIResponse and replicating the code of the original WSGIResource's render() code. Anyhow, I can't think of a better/more elegant solution with the current implementation.
I'll appreciate any comment on this.
Thank you.
Cristiano

On 09:58 pm, cristiano.paris@gmail.com wrote:
Hi,
I'm playing with Django (1.1.1) under Twisted Web (9.0.0) through the WSGI interface. When using my web app under the test server with sqlite3 as the DBMS, I'm having troubles since in-memory sqlite3 DBs can't be shared among threads.
The solution I came up with was to run the WSGIResource in the main thread. In order to do so, I subclassed the WSGIResource as follows:
Can you use a thread-local SQLite3 connection, or is that logic buried too deeply in some other code?
Another option (I think - untested) would be to give WSGIResource a different implementation of the thread pool interface:
class NotThreadPool: def callInThread(self, f, *a, **kw): f(*a, **kw)
Jean-Paul

On Tue, Feb 2, 2010 at 11:13 PM, exarkun@twistedmatrix.com wrote:
... Can you use a thread-local SQLite3 connection, or is that logic buried too deeply in some other code?
It is, so this is not an option.
Another option (I think - untested) would be to give WSGIResource a different implementation of the thread pool interface:
class NotThreadPool: def callInThread(self, f, *a, **kw): f(*a, **kw)
Well, that would work too but I think it isn't more elegant than my solution yet being shorter, as you still have to know how the _WSGIRequest's code works.
A better option would be to delegate the threading strategy to subclasses of a generic "adapter" class which:
1 - Turns a Twisted Web request to a WSGI environment upon creation (i.e. in the __init__ method), adapts the input/output/error streams and so on. 2 - Let the class user start the WSGI application, whatever this means (start a thread or passing control straight to 3). 3 - Calls the WSGI application after starting to get the output from it. 4 - Writes the output the client.
The adapter class provides 1 and 3. Since 2 and 4 deal with the threading/non threading strategy, they wouldn't be directly implemented by the adapter class: they are implemented in subclasses providing the wanted threading strategy.
My two cents.
Cristiano

On 07:56 am, cristiano.paris@gmail.com wrote:
On Tue, Feb 2, 2010 at 11:13 PM, exarkun@twistedmatrix.com wrote:
... Can you use a thread-local SQLite3 connection, or is that logic buried too deeply in some other code?
It is, so this is not an option.
Another option (I think - untested) would be to give WSGIResource a different implementation of the thread pool interface:
class NotThreadPool: � �def callInThread(self, f, *a, **kw): � � � �f(*a, **kw)
Well, that would work too but I think it isn't more elegant than my solution yet being shorter, as you still have to know how the _WSGIRequest's code works.
I disagree. The fact that a threadpool is used is part of the public interface. The public WSGIResource class accepts a threadpool as an argument to its initializer. The threadpool interface itself is public.
Basically, this is a parameter you're supposed to be passing in, and you're supposed to have it configured in a way which is appropriate for your application.
A better option would be to delegate the threading strategy to subclasses of a generic "adapter" class which:
1 - Turns a Twisted Web request to a WSGI environment upon creation (i.e. in the __init__ method), adapts the input/output/error streams and so on. 2 - Let the class user start the WSGI application, whatever this means (start a thread or passing control straight to 3). 3 - Calls the WSGI application after starting to get the output from it. 4 - Writes the output the client.
The adapter class provides 1 and 3. Since 2 and 4 deal with the threading/non threading strategy, they wouldn't be directly implemented by the adapter class: they are implemented in subclasses providing the wanted threading strategy.
My two cents.
I'd have a hard time deciding whether this is an improvement without seeing an actual implementation. I'm not convinced it's necessary for your use-case, though.
Jean-Paul

On Wed, Feb 3, 2010 at 2:21 PM, exarkun@twistedmatrix.com wrote:
... I disagree. The fact that a threadpool is used is part of the public interface. The public WSGIResource class accepts a threadpool as an argument to its initializer. The threadpool interface itself is public.
Basically, this is a parameter you're supposed to be passing in, and you're supposed to have it configured in a way which is appropriate for your application.
Ok, but you need to provide all the methods because you are not supposed to know which methods WSGIResource is going to use.
Cristiano

On 01:27 pm, cristiano.paris@gmail.com wrote:
On Wed, Feb 3, 2010 at 2:21 PM, exarkun@twistedmatrix.com wrote:
... I disagree. �The fact that a threadpool is used is part of the public interface. �The public WSGIResource class accepts a threadpool as an argument to its initializer. �The threadpool interface itself is public.
Basically, this is a parameter you're supposed to be passing in, and you're supposed to have it configured in a way which is appropriate for your application.
Ok, but you need to provide all the methods because you are not supposed to know which methods WSGIResource is going to use.
Sure.
Cristiano
Twisted-web mailing list Twisted-web@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-web
participants (2)
-
Cristiano Paris
-
exarkun@twistedmatrix.com