[Zope] 'helper' classes in External Methods

tony mcdonald tony.mcdonald@ncl.ac.uk
Sat, 04 Mar 2000 13:57:09 +0000


> I think it is not a good idea to define classes in external methods. It is
> better to define them somewhere in Shared (see the directory DC under
> lib/python/Shared for example) and import them in your external method. 
> 
> import Shared.Tony.helper

I've never used the DC Shared folder before. I've had a look in there as you
suggest and found some interesting things there. Time to read the docs on this
aspect I think...

> 
>  They can be very handy especially since python is way more elegant and
> easy for complex logic in relation to DTML.
> 
> 

Definitely. I'm now using the XXX PythonMethods that Evan Simpson contributed
and it's *definitely* helping to speed up development time.

>> What I would like to do is load up a template_lookups dictionary with 
>> quite a few entries;
>> 
>> for template_id in self.Actors.RENDER.objectIds():
>>          renderer = eval("self.Actors.RENDER.%s" % template_id)
>>          template_lookups[template_id] = renderer
>> 
>> Thing is, I need access to the ZODB in one of my methods later in the 
>> module and so the above code doesn't work (too many 'selfs'!).
>> 
>> Anyone got any ideas?
> 
> Not sure. need some more info. Did you try to use getattr to get to
> object?
> 
> 

Sorry, I should be more specific. The above code is in a method - def
supercascade(self, tag_id): which is called from Zope with a query_string,
tag_id=231441.

That code works, but I need to load up the renderers everytime supercascade is
called. I'm looking at the helper classes to see if I can't load up the
template_lookups array once. Having said that, supercascade isn't called
anywhere near the number of times that make_html (the method that generates
the HTML for display) is, so it's possible that I'm flogging a dead horse
here.

> tmp=self.Actors.RENDER
> renderer=getattr(tmp,template_id)
> 
> What kind of object is template_id?

It's a DTML document of the form (this example has id = lecture_info);
---
<hr>
<p class="<dtml-var class>"><dtml-var content null="&nbsp;"></p>
---

make_html then has a snippet in it so;
try:
    template_str = template_lookups[theclass]
    template = DocumentTemplate.HTML(template_str)
    theresult = template(self, content=content, src=src, thetag=thetag,
level=level, the
class=theclass, header=header)
    return "<!-- theclass [%s] thetag [%s]  -->" % (theclass, thetag)  +
theresult
except:
    pass

which will then render the HTML appropriately. The *really* neat thing is when
you have more complex DTML in the template that has ZSQL calls etc. 

It works well, but I want to speed it up a bit - it can take up to 6 seconds
to render a 100k document, and if I've understood my Zope architecture
correctly, thats one thread used up (and I'm only using the default thread
count - I think it's six) until the request has finished. I'm sure that
previous messages on the list have implied that it's not worth changing the
number of threads to something like 32-64, but I'm not sure.

That's my main problem, people are hitting the site and generating lots of
requests that are in the >1 second range. With our Apache servers, we just
spawn ludicrous numbers of httpd processes and don't worry about it. Zope is a
different kettle of fish and I need to think differently about it.

> 
> Pavlos

Many thanks for your help Pavlos, I feel things are a quite a bit clearer now.

tone