Project

Profile

Help

Contention on LRUCache running xQuery from multiple threads

Added by Fady Moussallam over 5 years ago

Using xquery on Saxon-PE 9.7.0-18, with 4 concurrent threads, all running the same query, I am seeing a lot of contentions between threads, with the following stack trace:

pool-1-thread-3 [BLOCKED] java.util.Collections$SynchronizedMap.get(Object) net.sf.saxon.expr.sort.LRUCache.get(Object) LRUCache.java:58 net.sf.saxon.lib.ConversionRules.getConverter(AtomicType, AtomicType) ConversionRules.java:196 net.sf.saxon.expr.CastExpression.doCast(AtomicValue, XPathContext) CastExpression.java:366 net.sf.saxon.expr.CastExpression.evaluateItem(XPathContext) CastExpression.java:405 net.sf.saxon.expr.CastExpression.evaluateItem(XPathContext) CastExpression.java:31 net.sf.saxon.expr.GeneralComparison.effectiveBooleanValue(XPathContext) GeneralComparison.java:616 net.sf.saxon.expr.instruct.Choose.choose(XPathContext) Choose.java:865 net.sf.saxon.expr.instruct.Choose.evaluateItem(XPathContext) Choose.java:893 net.sf.saxon.expr.LetExpression.evaluateItem(XPathContext) LetExpression.java:521 net.sf.saxon.expr.parser.ExpressionTool.evaluate(Expression, int, XPathContext, int) ExpressionTool.java:314 net.sf.saxon.expr.LetExpression.eval(XPathContext) LetExpression.java:500 net.sf.saxon.expr.LetExpression.processLeavingTail(XPathContext) LetExpression.java:702 net.sf.saxon.expr.instruct.Block.processLeavingTail(XPathContext) Block.java:653 net.sf.saxon.expr.instruct.Instruction.process(XPathContext) Instruction.java:149 net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(XPathContext, NodeInfo) ElementCreator.java:364 net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(XPathContext) ElementCreator.java:311 net.sf.saxon.expr.instruct.Instruction.process(XPathContext) Instruction.java:149 net.sf.saxon.expr.flwor.ReturnClausePush.processTuple(XPathContext) ReturnClausePush.java:37 net.sf.saxon.expr.flwor.ForClausePush.processTuple(XPathContext) ForClausePush.java:44 net.sf.saxon.expr.flwor.FLWORExpression.process(XPathContext) FLWORExpression.java:864 net.sf.saxon.expr.instruct.UserFunction.process(Sequence[], XPathContextMajor) UserFunction.java:626 net.sf.saxon.expr.UserFunctionCall.process(XPathContext) UserFunctionCall.java:549 net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(XPathContext, NodeInfo) ElementCreator.java:364 net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(XPathContext) ElementCreator.java:311 net.sf.saxon.expr.instruct.Instruction.process(XPathContext) Instruction.java:149 net.sf.saxon.expr.flwor.ReturnClausePush.processTuple(XPathContext) ReturnClausePush.java:37 net.sf.saxon.expr.flwor.ForClausePush.processTuple(XPathContext) ForClausePush.java:44 net.sf.saxon.expr.flwor.FLWORExpression.process(XPathContext) FLWORExpression.java:864 net.sf.saxon.expr.instruct.UserFunction.process(Sequence[], XPathContextMajor) UserFunction.java:626 net.sf.saxon.expr.UserFunctionCall.process(XPathContext) UserFunctionCall.java:549 net.sf.saxon.query.XQueryExpression.run(DynamicQueryContext, Result, Properties) XQueryExpression.java:414 net.sf.saxon.s9api.XQueryEvaluator.run(Destination) XQueryEvaluator.java:370 org.talend.transform.xquery.SaxonProcessor.run(Source, ContentHandler) SaxonProcessor.java:48 org.talend.transform.engine.xquery.XQueryConcurTest$MyCallable.call() XQueryConcurTest.java:114 org.talend.transform.engine.xquery.XQueryConcurTest$MyCallable.call() XQueryConcurTest.java:1 java.lang.Thread.run()

Any ideas if there is a way to improve this?

Thank you!


Replies (3)

Please register to reply

RE: Contention on LRUCache running xQuery from multiple threads - Added by Michael Kay over 5 years ago

Thanks for reporting it (though unfortunately you chose the wrong forum - this is nothing to do with Saxon/C).

I'm a little surprised that it should happen with only 4 threads, but I guess it depends on what the query is doing. Any chance you could share the query code? I don't think there's going to be any workaround that doesn't involve some changes to the way the query is written.

As this is Saxon-PE, the code presumably isn't schema-aware, so we're talking about casts/conversions between built-in types.

One possible way forward would be to use a ThreadLocal cache, though there seems to be a lot of advice against using ThreadLocal these days.

Could I ask you please to raise it as an issue on the Issues tracker and then we can follow it up from there.

RE: Contention on LRUCache running xQuery from multiple threads - Added by Fady Moussallam over 5 years ago

Ah, it's my first post and my landing page only had Saxon/C and Saxon-CE as projects. Sorry for posting to the wrong place.

A coworker also pointed out a very similar issue was already discussed here: https://saxonica.plan.io/boards/3/topics/6004, so sorry again.

In our case it is unlikely we can significantly reduce the number of casts, we will try though.

Anyway, thank you for your prompt reply, here is the bug report https://saxonica.plan.io/issues/3294. I have attached our xquery FYI.

Fady

RE: Contention on LRUCache running xQuery from multiple threads - Added by Fady Moussallam about 5 years ago

Just ran a concurrent test on 9.7.0.19. All contentions on LRUCache are gone.

Thank you so much for the speedy fix!

    (1-3/3)

    Please register to reply