Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Thread safety issue for variable values with ph-schematron-pure 8.0.3 #182

Open
bertrand-lorentz opened this issue Nov 5, 2024 · 0 comments

Comments

@bertrand-lorentz
Copy link
Contributor

In the Schematron rules we use, a variable is defined at the top level and stores a value for the XML being validated:

<let name="noticeSubType" value="/*/ext:UBLExtensions/.../cbc:SubTypeCode/text()"/>

It is then used in lots of rule contexts:

<rule context="/*[$noticeSubType = '1']">
...
<rule context="/*[$noticeSubType = '2']">
...
<rule context="/*/cac:ContractingParty[$noticeSubType = '1']">
...
<rule context="/*/cac:ContractingParty[$noticeSubType = '2']">

When validating XML files in separate threads, the value of this variable is sometimes changed during the validation of an XML file.
This is visible in the SVRL, which shows that rules for other values are fired (simplified example):

<?xml version="1.0" encoding="UTF-8"?>
<svrl:schematron-output xmlns:svrl="http://purl.oclc.org/dsdl/svrl" title="eForms schematron rules">
. . .
    <svrl:fired-rule context="/*[$noticeSubType = '1']" />
    <svrl:fired-rule context="/*/cac:ContractingParty[$noticeSubType = '2']" />
. . .

This only happens when the application is under load (in production...): concurrent requests to validate different XML that have different values for the variable.

Here's what I think is happening:
1/ During the bind part, a single instance of XPathLetVariableResolver is created, and kept in the PSXPathBoundSchema object
2/ ThreadA starts validating an XML: variables are evaluated and their value stored in XPathLetVariableResolver, and some rules are executed
3/ ThreadB starts validating another XML: variables are evaluated and their value stored in the same XPathLetVariableResolver, overwriting the values set by ThreadA
4/ ThreadA executes rules that reference variables, so uses the values set by ThreadB.

My first idea is to make the map that stores variable values ThreadLocal.
But I guess that first we need a way to reproduce the problem reliably...

Any help or suggestions are welcome !

@phax phax self-assigned this Nov 5, 2024
bertrand-lorentz added a commit to bertrand-lorentz/ph-schematron that referenced this issue Nov 5, 2024
This test currently fails because the value of the "var" variable" set
by one thread is overwritten by the other thread.
Theoretically this test would fail or not depending on how the 2 threads
are executed and interweaved. But it seems to always fail, so no further
complication is added for now.
bertrand-lorentz added a commit to bertrand-lorentz/ph-schematron that referenced this issue Nov 5, 2024
To ensure that variable values are not overwritten when different XML
are validated on separate threads, store the variable values in aborts
ThreadLocal map.

Fixes issue phax#182.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants