From: Stephen D. <sd...@gm...> - 2005-12-30 07:46:13
|
On 12/29/05, Andrew Piskorski <at...@pi...> wrote: > On Thu, Dec 29, 2005 at 07:11:35PM -0700, Stephen Deasey wrote: > > > Still to think about are per-thread Tcl caches. The main reason for > > these are that you can put Tcl objects in the cache, not just their > > string rep, which is particularly useful for already-compiled byte > > code -- i.e. for *.tcl pages. > > Tcl code in *.tcl pages (not in procs) can be, has been, and I hope > currently still is cached in OpenACS using the mechanism Rob Mayoff > added to AOLserver 3.3 long ago. Essentially, all Tcl code in each > *.tcl page is automatically "compiled" to Tcl procs on first > execution, and those procs' bytecode is then cached via ns_cache. > Each connection thread does its own entirely independent cacheing, but > it worked fine and apparently was a substantial speed up for some ACS > sites when switching from AOLserver 3.3+ad11 or 3.3+ad12 (I forget > which) to 3.3+ad13. > > Actually, I'm not sure whether that code is currently active or not. > It sounds as if the feature may have broke during the AOLserver 3.x to > 4.x transition and never been repaired. See here for more info: > > http://sourceforge.net/tracker/?func=3Ddetail&aid=3D689515&group_id=3D3= 152&atid=3D353152 ACS hasn't used that for a long time. It handles *.adp and *.tcl pages itself. ACS creates procs named after the file to evaluate at runtime. It does this for each thread the first time a *.tcl page is called. There is no eviction policy, therefore it's more of a memory leak than a cache. Rob's old method was to slurp the contents of the *.tcl file into a variable and eval it. The variable would be byte code compiled the first time it was evaled. Because of limitations in Tcl, byte code objects cannot be shared across threads, so to save the byte code it was necessary to have a per-thread Tcl cache. > Does Rob's cacheing cover the functionality you want, or are you > thinking of cacheing of some other sort of Tcl objects? Rob's per-thread Tcl cache can cache any Tcl object. It's just a hash table with an eviction policy (max size or time limit). > > The best solution for caching byte code might be to share the > > mechanism with ADP pages. They currently have a pre-thread cache of > > script blocks, and a per-server cache of text blocks, for each page. > > AOLserver 4.5 adds a per-server output cache. We could use this for > > *.tcl pages as well, perhaps negating the need for per-thread Tcl > > caches. That still leaves Tcl objects like lists or dictionaries that > > you may not want to stringify on each access. > > Ah. I think Rob's code above solely cached compiled Tcl bytecode (in > what form I don't know), not Tcl_Obj representations of anything. > I've also no idea whether it plays nicely with Zoran's Ttrace > extension or not. > > But, we already have centralized server-wide cacheing of Tcl_Obj's via > Zoran's Tcl Threads Extension, right? So, is there any real use case > for a per-thread Tcl_Obj cache? (Offhand I can't think of one, but > then I don't think I've ever really used ns_cache directly at all, > only the simplified util_memoize facility of OpenACS, so I'm not the > right person to ask.) Kind of. The Tcl thread package has nsv arrays, with the added twist that certain Tcl objects do not have to be serialised to their string form. This isn't a cache though -- there's no eviction policy. Also, compared to a per-thread Tcl cache there will be locking overhead. It's a trade off though. If you have a small amount of data and/or if the data is expensive to serialise or is to be evaled, it may make sense to put it in a per-thread cache. Otherwise, save the memory and share it between threads. If you look at the old nscache module you'll see basically two completely independent code paths for per-thread and shared caches. I didn't want to go that far. I also thought that perhaps the main use case was for caching byte code, and that might be better done with the ADP caching mechanism. But I don't know, there may be situations where a per-thread cache is worht while and we should add that...? |