Reputation: 57
I'm trying to put slow computations inside threads, and getting an error "Request.write called on a request after Request.finish was called."
I've looked through answers already, and find exact the same question, but the solution not working for me. Please advise.
from twisted.web.server import Site, NOT_DONE_YET
from twisted.web.resource import Resource
from twisted.internet import reactor, threads
from twisted.python import log
import sys
import time
def SlowComputation():
time.sleep(10)
return "Lang Computation Result"
def FastComputation():
return "Fast Computation Result"
class PerformComputation(Resource):
def Success(self, request):
request.write('Success')
request.finish()
def Failure(self, request):
request.write('Failure')
request.finish()
def render_GET(self, request):
if 'fast' in request.args:
d = threads.deferToThread(FastComputation)
d.addCallback(self.Success(request))
return NOT_DONE_YET
if 'slow' in request.args:
d = threads.deferToThread(SlowComputation)
d.addCallback(self.Success(request))
return NOT_DONE_YET
log.startLogging(sys.stdout)
root = Resource()
root.putChild("calculate", PerformComputation())
factory = Site(root)
reactor.listenTCP(8880, factory, interface='localhost')
reactor.run()
Upvotes: 2
Views: 1723
Reputation: 48335
This:
d.addCallback(self.Success(request))
is the same as:
temp = self.Success(request)
d.addCallback(temp)
which, given the definition of Success
is the same as:
request.write('Success')
request.finish()
temp = None
d.addCallback(None)
This probably fails with Request.write called on a request after Request.finish was called. because d.addCallback(None)
raises an exception and the server tries to report the error as the response. However, since finish
has already been called it can't write the error.
The correct way to add a callback to a Deferred
with an extra argument is d.addCallback(self.Success, request)
. Callbacks on a Deferred
always get passed the result of the Deferred
as the first argument, though - so the correct signature for Success
is:
def Success(self, result, request):
...
Upvotes: 3