I'm reading Twisted Network Programming Essentials. In Chapter 5, there is this code:
# encoding: utf-8
import sys
from twisted.internet import reactor
from twisted.internet.defer import Deferred
from twisted.internet.protocol import Protocol
from twisted.web.client import Agent
class ResourcePrinter(Protocol):
def __init__(self, finished):
self.finished = finished
def dataReceived(self, data):
'''
data seems comes from response not transport
'''
print data
def connectionLost(self, reason):
self.finished.callback(None) # Fire with None, no callback in deferred: finished
def printResource(response):
finished = Deferred()
print "idf: ", id(finished)
# Dispatch IProtocol to handle response
response.deliverBody(ResourcePrinter(finished))
return finished
def printError(failure):
print >> sys.stderr, failure
def stop(result):
print type(result) # Result is None, not return value from printResource, why?
reactor.stop()
if len(sys.argv) != 2:
print >> sys.stderr, "Usage: python e5-3.py URL"
exit(1)
agent = Agent(reactor)
d = agent.request("GET", sys.argv[1])
d.addCallbacks(printResource, printError)
d.addBoth(stop)
reactor.run()
- Why there are two deferred? →
dandfinished, how are they combined? - The return value of
printResourceisfinished, why not pass to callback stop? (The arg result isNone.) - What is the flow of the response, where does it begin and end? The flow seems to be that,
dgets the response in chunks and passes it to callbackprintResource. InprintResource, it dispatches toIProtocolto handle it. How does it work? Usually,IProtocolreceives data fromITransport, but here it seems not.