[Zope3-dev] Context and Component Lookup

Phillip J. Eby pje@telecommunity.com
Wed, 06 Aug 2003 10:09:39 -0400


At 06:57 AM 8/6/03 -0400, Jim Fulton wrote:

>To implement this simpler component lookup strategy will require
>resorting to a thread-global variable. This thread global variable
>will be set during URL traversal and (probably) cleared when a request
>is closed.

You might be able to do that a lot more simply, if you just use an explicit 
context object, and the context object has methods to look up views, 
etc.  In peak.web, I use a TraversalContext class, mainly to be able to 
compute relative and absolute URLs of resources, but you could use a 
similar approach for this.

Basically, a TraversalContext holds a reference to the interaction (a 
per-request IPublication, but for zope.app you could just hold the request 
instead), a traversable (the content object adapted to a traversing 
protocol) and a subject (the original content object).  A traversal context 
also knows its parent context.

By calling a method on a traversal context, passing in a name, you can get 
a new traversal context that's a child of the previous context, and has 
traversed to the appropriate content object.  So, in peak.web, the main 
thing that gets passed around are these context objects, because they give 
access to everything: the request, traversal adapters, and content 
objects.  They can safely cache a variety of things, they can delegate 
aspects of their behavior to the traversal or content objects, and so 
on.  And, in peak.web they have the equivalent responsibility of adapting 
content objects to viewable entities.  See ITraversalContext:

http://cvs.eby-sarna.com/PEAK/src/peak/web/interfaces.py?rev=HEAD&content-type=text/vnd.viewcvs-markup



>   In the unlikely event that a thread spawns a new thread,
>the global variable would be carried to the subthread, providing that
>a specialized API is used to spawn the subthread.  I don't really like
>using thread globals (or any globals, for that matter), however, I
>think that this is a case where the improvement in simplicity and
>efficiency of component lookup justifies the global variable.

*Shudder*.  I think you'd be better off just making the context explicit, 
but perhaps I'm biased.  I suppose it also might require a lot more 
refactoring in zope.app to replace use of implicitly context-wrapped 
objects with an explicit context.  For peak.web, I only had a few modules 
to refactor when I realized this would simplify things.