<font size="2"><span style="font-family: courier new,monospace;">Dear List:<br><br>I am having a heck of a time trying to figure out why this traceback is happening, and I was hoping that you could shed some light on the situation. I am sorry for bothering you with this simple thing, but I can't seem to figure it out!
<br><br>The code and traceback are below. The traceback only happens when I call </span></font><font size="2"><span style="font-family: courier new,monospace;">httprequest.writeResponse(httpresponse) from a callback. When the same code is called inline and not in a deferred, it works just fine. Even stranger is that the response is written to the client even though the traceback occurs.
<br><br>An explanation of what I am trying to do: <br><br>A consumer requests data. </span></font><font size="2"><span style="font-family: courier new,monospace;">If there is data in the queue when the consumer first checks, return the result right away.
</span></font><font size="2"><span style="font-family: courier new,monospace;">If there is no data present, return a deferred and wait. When the producer inserts data into the queue, check if there is a consumer waiting. If so, begin callback chain on consumer.
<br><br>The code works fine (no traceback) in the case where there is no deferred needed (in QueueCache.maybedefer). When there is a deferred, the traceback happens during the callback (in QueueCache.put). Again, the consumer actually gets the correct result, but the traceback still occurs!
<br><br></span></font><font size="2"><span style="font-family: courier new,monospace;">Any ideas?</span></font><br><font size="2"><span style="font-family: courier new,monospace;"><br>Thanks in advance!<br><br>~P </span>
</font><br><font size="2"><span style="font-family: courier new,monospace;"><br><br>from twisted.internet import reactor, defer</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
from twisted.web2 import http, responsecode</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">import Queue</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">TIMEOUT = 10</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">def respond(result, httprequest):
</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> httpresponse = http.Response(responsecode.OK, {}, stream=result)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> httprequest.writeResponse(httpresponse)</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
class QueueCache(object):</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> def __init__(self):</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
self.queue = {}</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> self.defer = {}</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> def get_data(self, xSig):</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
return self.get_queue(xSig).get_nowait()</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> def push_data(self, xSig, value):
</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> self.get_queue(xSig).put(value)</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> def get_queue(self, xSig):</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> try:</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> return self.queue[xSig]</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> except KeyError:</span>
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> q = Queue.Queue()</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
self.queue[xSig] = q</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> return q</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> def defer_request(self, xSig, httprequest):</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> if self.defer.has_key
(xSig):</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> raise Exception("Client %s already has a deferred request!" %(xSig))</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> def timeout(deferred, request):</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
xSig = request.args['X-Signature'][0]</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> try:</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> self.defer.pop(xSig)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> except KeyError:</span>
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> print 'Timeout called and xSig `%s` was not in cache!' % xSig</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> respond('ACK',request)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> </span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> d = defer.Deferred()</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> d.addCallback(respond, httprequest)
</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> d.setTimeout(TIMEOUT, timeout, httprequest)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
self.defer[xSig] = d</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> return d</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> def put(self, data):</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> xSig = data['X-Signature']
</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> try:</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
d = self.defer.pop(xSig)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> d.callback(data['message'])</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> except KeyError:</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> self.push_data(xSig,data)</span>
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> </span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> def maybedefer(self, httprequest):
</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> xSig = httprequest.args['X-Signature'][0]</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
try:</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> data = self.get_data(xSig)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
result = http.Response(</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> responsecode.OK,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> {},</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> stream=data['message']</span>
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> )</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> except
Queue.Empty:</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> result = self.defer_request(xSig, httprequest)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> return result</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> </span><br style="font-family: courier new,monospace;">
-----------------------------------------------------------------------------------------------------<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">2007-09-25 18:38:38-0700 [-] Original exception:
</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">2007-09-25 18:38:38-0700 [-] Unhandled Error</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
Traceback (most recent call last):</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> File "C:\Projects\PyServer\twisted\internet\defer.py", line 304, in _startRunCallbacks
</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> File "C:\Projects\PyServer\twisted\internet\defer.py", line 317, in _runCallbacks
</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> File "C:\Projects\PyServer\twisted\internet\defer.py", line 281, in _continue
</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> File "C:\Projects\PyServer\twisted\internet\defer.py", line 277, in unpause
</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> --- <exception caught here> ---</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> File "C:\Projects\PyServer\twisted\internet\defer.py", line 317, in _runCallbacks</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> File "C:\Projects\PyServer\twisted\web2\server.py", line 518, in _cbFinishRender</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> exceptions.TypeError: html is not a resource or a response</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
2007-09-25 18:38:39-0700 [-] Unhandled error in Deferred:</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">2007-09-25 18:38:39-0700 [-] Unhandled Error</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> Traceback (most recent call last):</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> File "C:\Projects\PyServer\twisted\internet\defer.py", line 317, in _runCallbacks
</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> File "C:\Projects\PyServer\twisted\web2\server.py", line 476, in _processingFailed
</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> File "C:\Projects\PyServer\twisted\internet\defer.py", line 200, in addErrback
</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> File "C:\Projects\PyServer\twisted\internet\defer.py", line 182, in addCallbacks
</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> --- <exception caught here> ---</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> File "C:\Projects\PyServer\twisted\internet\defer.py", line 317, in _runCallbacks</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> File "C:\Projects\PyServer\twisted\web2\server.py", line 492, in _processingReallyFailed</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> File "C:\Python24\lib\site-packages\twisted\web2\http.py", line 446, in writeResponse</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
self.chanRequest.writeHeaders(response.code, response.headers)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> File "C:\Projects\PyServer\twisted\web2\channel\http.py", line 431, in writeHeaders
</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> File "C:\Projects\PyServer\twisted\web2\channel\http.py", line 466, in _writeHeaders
</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> exceptions.AttributeError: 'HTTPChannelRequest' object has no attribute 'transport'
</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"></font>