[Twisted-Python] Deferred getChild

Christopher Armstrong radix at twistedmatrix.com
Mon Oct 7 10:24:38 EDT 2002


I've implemented the Deferred support for getChild. I'd like to get
glyph's approval of this before I check it in, and I'm sending it to
TPML for general commentary.

getChildForRequest is now recursive in the general non-Deferred case,
I'm not sure if anyone has issues with this. I think I might be able
to convert it to a while loop that only recurses (well, horizontally
recurses ;-)) in the Deferred-result case.

Index: server.py
===================================================================
RCS file: /cvs/Twisted/twisted/web/server.py,v
retrieving revision 1.81
diff -u -r1.81 server.py
--- server.py	5 Oct 2002 12:15:11 -0000	1.81
+++ server.py	7 Oct 2002 14:21:02 -0000
@@ -42,7 +42,7 @@
 
 # Twisted Imports
 from twisted.spread import pb, refpath
-from twisted.internet import reactor, protocol
+from twisted.internet import reactor, protocol, defer
 from twisted.protocols import http
 from twisted.python import log, reflect, roots, failure, components
 from twisted import copyright
@@ -146,12 +146,17 @@
         self.postpath = map(urllib.unquote, string.split(self.path[1:], '/'))
         try:
             resrc = self.site.getResourceFor(self)
-            self.render(resrc)
+            if isinstance(resrc, defer.Deferred):
+                resrc.addCallback(self.render)
+                resrc.addErrback(self.processingFailed)
+            else:
+                self.render(resrc)
         except:
             self.processingFailed(failure.Failure())
 
     def render(self, resrc):
         try:
+            print resrc
             body = resrc.render(self)
         except UnsupportedMethod, e:
             allowedMethods = e.allowedMethods
@@ -449,7 +454,7 @@
         # servers and disconnected sites.
         request.sitepath = copy.copy(request.prepath)
         request.acqpath = copy.copy(request.prepath)
-        return self.resource.getChildForRequest(request)
+        return self.resource.getChildForRequest(request=request)
 
 
 import html
Index: resource.py
===================================================================
RCS file: /cvs/Twisted/twisted/web/resource.py,v
retrieving revision 1.20
diff -u -r1.20 resource.py
--- resource.py	25 Sep 2002 08:40:36 -0000	1.20
+++ resource.py	7 Oct 2002 14:21:02 -0000
@@ -122,21 +122,31 @@
 
         return self.getChild(path, request)
 
-    def getChildForRequest(self, request):
+    def getChildForRequest(self, resrc=None, request=None):
         """(internal) Get a child of mine dependant on a particular request.
 
         This will be called on me as a top-level resource of a site in order to
         retrieve my appropriate child or grandchild to display.
         """
-        res = self
-        while request.postpath and not res.isLeaf:
+        assert request, "No, that's not _really_ an optional argument."
+        res = resrc or self
+        if request.postpath and not res.isLeaf:
             pathElement = request.postpath.pop(0)
+            print "doing", pathElement, "...",
             request.acqpath.append(pathElement)
             request.prepath.append(pathElement)
             res = res.getChildWithDefault(pathElement, request)
-        return res
+            print "and got", res
 
+            #conditional horizontal or vertical recursion!
+            if isinstance(res, defer.Deferred):
+                #the caller adds an errback, so i don't need to
+                return res.addCallback(self.getChildForRequest, request)
+            else:
+                return self.getChildForRequest(res, request)
+        return res
 
+        
     def putChild(self, path, child):
         """Register a child with me.
         """





More information about the Twisted-Python mailing list