commons-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Arnaud Masson <arnaud.mas...@kikamedical.com>
Subject Re: [Jelly] nested compileScript() with import ?
Date Mon, 06 Dec 2004 17:10:54 GMT
Hans Gilde wrote:

>Arnaud,
>
>You're right about how JSP works; maybe you could file an issue about this
>in Jelly's jira? This seems like something that many web users would want.
>
>  
>
done (sorry for the double post #170/171, the server wasn't responding)

>Sorry to introduce problems but...
>
>To get the benefit of your solution, you will need to reuse the cache
>between Servlet invocations. The basic Jelly Servlet does not reuse the
>JellyContext between invocations. Here's the pain: the context isn't
>entirely thread safe (actually, the parser isn't thread safe and the context
>uses a single parser).
>
>Here's what you can do:
>
>Set the HashMap into the context before invoking the script. If inherit is
>true (by default), the Map will be accessible throughout your entire script.
>
>Now that your Servlet has a handle on the HashMap, you can keep it in an
>instance variable (must be a thread safe HashMap) or as an application
>variable or whatever.
>
>  
>
Currently I put the JellyContext (including the script cache) in the web 
session.
When I use this JellyContext , I do a synchronized(myContext) {...} to 
avoid the threading problem.
Of course the cache isn't shared across session.

Your solution is better but the per-session solution has one advantage.
You can easily purge the cache when you open a new session, which is 
useful when you modify the jelly scripts.
I have tried to use URLConnection.getDate() to discard the cache,
but it doesn't work on the jndi URL provided by tomcat with 
ServletContext.getResource(), it always returns 0.
Any idea how I can manage cache update ?

>-----Original Message-----
>From: Arnaud Masson [mailto:arnaud.masson@kikamedical.com] 
>Sent: Monday, December 06, 2004 4:06 AM
>To: Jakarta Commons Users List
>Subject: Re: [Jelly] nested compileScript() with import ?
>
>Hans Gilde wrote:
>
>  
>
>>Ok, it sounds reasonable to want those caching conditions. But for my own
>>curiosity, why do you want them? Are you in a tight memory situation or is
>>it a perfectionist thing?
>>
>> 
>>
>>    
>>
>It's for speed, especially for Script.run().
>I must run many small scripts to build page, so I would like to minimize 
>IO and XML parsing.
>The outputs of the scripts are assembled in a big DOM,
>under the control of a java loop which also makes some modifications to 
>the DOM.
>(I use a custom ContentHandler so that jelly output is directly added in 
>the document without parsing.)
>
>I think that in a classic JSP, all included pages are compiled when the 
>main jsp  is compiled,
>so there is no performance penalty there. I would like the same thing in 
>jelly.
>
>  
>
>>What's wrong with using JellyContext variables? It's pretty much what
>>they're there for.
>>
>> 
>>
>>    
>>
>I had the idea that the cached scripts were technical details and should 
>not be at the same level as user variables.
>This time, it's probably a "perfectionist thing" ! :-)
>
>  
>
>>You can think of a JellyContext as a scope. At each level of XML tag, you
>>get a new JellyContext (a new scope). Export says "when a variable is set
>>into the current scope, should I automatically put it into the scope
>>    
>>
>above"?
>  
>
>>Inherit says "when creating a new scope, should I give it all the variables
>>    
>>
>>from the current scope"?
>  
>
>>If a Tag wants to set a variable in a context (scope) that's higher up in
>>the tree, there are two choices: use export=true or find the parent context
>>(while ((parent = getParent()) != null)).
>>
>>To find a variable that's been set into a context above yours, either use
>>inherit=true or findVariable.
>>
>>I'd suggest this solution:
>>
>>Have your Tag find the top level context (while ((parent = getParent()) !=
>>null)). Use a single variable name in this context, say
>>    
>>
>my_imported_scripts.
>  
>
>>That variable will be a single HashMap from uri to parsed Script instance.
>> 
>>
>>    
>>
>Ok, I'm going to try this.
>
>  
>
>>As you saw, compilable tags are sort of compiled, but they don't get a
>>context or their attributes at that point. The problem with compilable tags
>>(I don't recommend using them) is that they're only compiled with respect
>>    
>>
>to
>  
>
>>the thread that compiles them. If you run the same Script in a different
>>thread, those compiled tags won't be there. This is not true for a Script.
>>Once a Script is compiled, it stays compiled no matter where you use it.
>>
>> 
>>
>>    
>>
>I don't think I need the advanced Script based solution for now, the 
>cache map must be sufficient for me.
>
>Thanks for your help.
>
>  
>
>>Hans
>>
>>-----Original Message-----
>>From: Arnaud Masson [mailto:arnaud.masson@kikamedical.com] 
>>Sent: Sunday, December 05, 2004 5:06 PM
>>To: Jakarta Commons Users List
>>Subject: Re: [Jelly] nested compileScript() with import ?
>>
>>Yes,  I have copied the import tag and added the cache to the new tag.
>>It works fine, but I would like to reuse compiled scripts
>>- if several container scripts include the same sub script
>>- if a container script include the same sub script several times
>>
>>To do that, I currently use the JellyContext to cache compiled scripts 
>>with a call to setVariable(),
>>using a variable name based on the script uri... it works, but it's not 
>>really clean.
>>
>>Maybe a better way would be to override the compileScript() methods of 
>>the JellyContext
>>and add a cache of compiled scripts inside the context (indexed by 
>>uri/url) ?
>>
>>Also I am not sure how to handle the 'export' and 'inherit' parameters 
>>when I use compileScript+run instead of a single call to runScript().
>>
>>You say a Tag isn't compilable, but what's the "CompilableTag" ??
>>I tried to use it the but the attributes (uri,...) of my tag are empty 
>>when "compile" is called.
>>
>>Thanks for your help!
>>
>>
>>
>>.Hans Gilde wrote:
>>
>> 
>>
>>    
>>
>>>You could easily cache the imported script the first time it's run. This
>>>      
>>>
>is
>  
>
>>>a simple modification to the current import tag, so that it keeps the
>>>reference to the script. If you do this, why not add an attribute "cache"
>>>   
>>>
>>>      
>>>
>>to
>> 
>>
>>    
>>
>>>turn caching on/off and then submit it as a patch to the import tag?
>>>
>>>It would be a little harder, but not at all impossible, to make it cache
>>>   
>>>
>>>      
>>>
>>the
>> 
>>
>>    
>>
>>>imported script at compile time.
>>>
>>>If not, the basic idea is this:
>>>
>>>A Tag isn't compilable, it's generated at runtime. A Script is compilable,
>>>it's generated at compile time. You need a special Script, not a special
>>>Tag. Scripts are very much like tags except that they need to be thread
>>>safe. Most of the time, a Script called TagScript is used. By default,
>>>      
>>>
>this
>  
>
>>>Script creates and caches Tag instances when it's run.
>>>
>>>Your new Script would compile the import at compile time. The result of
>>>compiling the import is, it self, a Script instance. At runtime, your
>>>   
>>>
>>>      
>>>
>>Script
>> 
>>
>>    
>>
>>>would simply pass control to the imported Script.
>>>
>>>You would also have to implement a custom TagLibrary. A TagLibrary gets to
>>>create a TagScript (implements Script) for every XML tag in its namespace.
>>>So, your TagLibrary would create a custom TagScript that would compile and
>>>keep the imported XML.
>>>
>>>-----Original Message-----
>>>From: Arnaud Masson [mailto:am@kikamedical.com] 
>>>Sent: Saturday, December 04, 2004 6:07 PM
>>>To: commons-user@jakarta.apache.org
>>>Subject: [Jelly] nested compileScript() with import ?
>>>
>>>hi
>>>
>>>in the current version of jelly "import" tag, it seems that imported 
>>>scripts are always parsed and recompiled each time the containing script 
>>>runs,
>>>even if this script has already been compiled.
>>>
>>>the problem is that  it isn't optimized if the compiled version of the 
>>>main script is cached.
>>>
>>>is it possible to compile all scripts included via <j:import ...> via a

>>>single call to jellyContext.compileScript() on the containing script ?
>>>should i write a custom tag to implement that (to replace import) ?
>>>
>>>thanks in advance
>>>
>>>arnaud
>>>
>>>
>>>
>>>
>>>---------------------------------------------------------------------
>>>To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
>>>For additional commands, e-mail: commons-user-help@jakarta.apache.org
>>>
>>>
>>>
>>>
>>>   
>>>
>>>      
>>>
>>---------------------------------------------------------------------
>>To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
>>For additional commands, e-mail: commons-user-help@jakarta.apache.org
>>
>>
>>---------------------------------------------------------------------
>>To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
>>For additional commands, e-mail: commons-user-help@jakarta.apache.org
>>
>>
>> 
>>
>>    
>>
>
>
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: commons-user-unsubscribe@jakarta.apache.org
>For additional commands, e-mail: commons-user-help@jakarta.apache.org
>
>
>  
>


Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message