[
https://issues.apache.org/jira/browse/WW-5147?focusedWorklogId=681165&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-681165
]
ASF GitHub Bot logged work on WW-5147:
--------------------------------------
Author: ASF GitHub Bot
Created on: 13/Nov/21 22:02
Start Date: 13/Nov/21 22:02
Worklog Time Spent: 10m
Work Description: JCgH4164838Gh792C124B5 commented on pull request #504:
URL: https://github.com/apache/struts/pull/504#issuecomment-968154566
I tried looking at `ASTChain` processing, and the behaviour you mentioned
above, by debugging really basic application. From what I can determine so
far, the cases where the source can be `null` looks like it was probably a
design choice. It seems to happen for compound node statements where there is
no value for the "parent node", so the "child node" cannot have a value. I am
not 100% certain, though, so if someone can see and explain things clearly,
please feel free to comment. :)
Looking into using a full-fledged cache (like _cache2k_ or _caffeine_,
possibly using the JSR107/JCache API to be provider-agnostic) for the
expression cache could be interesting. Alternatively, implementing a slightly
more sophisticated customization of the existing cache (without introducing any
new dependencies), could be interesting too. That could be a new feature
request for 2.6.x.
As for this PR and 2.6.x, given the explanation and arguments you have
provided, I think it seems reasonable to apply to 2.6.x, and see how things
behave. 👍
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
Issue Time Tracking
-------------------
Worklog Id: (was: 681165)
Time Spent: 2.5h (was: 2h 20m)
> OGNL valid expression is not cached and is parsed over again in some
> situations
> -------------------------------------------------------------------------------
>
> Key: WW-5147
> URL: https://issues.apache.org/jira/browse/WW-5147
> Project: Struts 2
> Issue Type: Bug
> Components: Core
> Affects Versions: 2.5.20
> Reporter: Pascal Davoust
> Priority: Major
> Fix For: 2.6, 2.5.28
>
> Time Spent: 2.5h
> Remaining Estimate: 0h
>
> Profiling an enterprise application under high load shows an unlikely number
> of invocations to method {{ognl.Ognl.parseExpression}} (representing a
> significant cumulated CPU time), despite having the OGNL expression cache
> enabled.
> Knowing that there is no dynamic expression in this application, this is
> puzzling: once each expression have been encountered, its parsed/compiled
> representation should be cached, avoiding the parsing phase entirely to only
> keep the execution phase.
> After investigation, this is due to the caching logic in method
> {{com.opensymphony.xwork2.ognl.OgnlUtil.compileAndExecute(String, Map<String,
> Object>, OgnlTask<T>}} (same applies to
> {{com.opensymphony.xwork2.ognl.OgnlUtil.compileAndExecuteMethod(String,
> Map<String, Object>, OgnlTask<T>)}} ) :
>
> {code:java}
> private <T> Object compileAndExecute(String expression, Map<String, Object>
> context, OgnlTask<T> task) throws OgnlException {
> Object tree;
> if (enableExpressionCache) {
> tree = expressions.get(expression);
> if (tree == null) {
> tree = Ognl.parseExpression(expression);
> checkEnableEvalExpression(tree, context);
> }
> } else {
> tree = Ognl.parseExpression(expression);
> checkEnableEvalExpression(tree, context);
> }
> final T exec = task.execute(tree);
> // if cache is enabled and it's a valid expression, puts it in
> if (enableExpressionCache) {
> expressions.putIfAbsent(expression, tree);
> }
> return exec;
> } {code}
>
>
> As shown above, on cache miss, the expression is parsed, then executed, and
> added to the cache {+}only after execution{+}.
> Problem is that the execution can fail (especially that Ognl makes use of
> exceptions quite extensively): in this case, the parsed AST is lost and not
> added to the cache.
> As a result, the same expression will go through the cache miss code path
> next time.
>
> Unless I'm mistaken, the AST of the parsed expression could be added to the
> cache right after parsing and validation, and before execution fires: an AST
> is obviously independant from any execution context so it can be reused over
> and over again.
>
> As a proof of concept, I patched our enterprise application with the changes
> above and ran the benchmark again: we experienced a very significant
> improvement in response times and CPU usage, between 10% to 30% decreased
> response times (knowing that these pages also perform time consuming tasks
> such as database updates and search engine lookups).
> I'm happy to provide a PR for you guys to have a look if you deem it worthy.
--
This message was sent by Atlassian Jira
(v8.20.1#820001)