davsclaus commented on code in PR #26311:
URL: https://github.com/apache/camel/pull/26311#discussion_r3989772222
##########
components/camel-python/src/main/java/org/apache/camel/language/python/PythonLanguage.java:
##########
@@ -75,19 +75,22 @@ public <T> T evaluate(String script, Map<String, Object>
bindings, Class<T> resu
}
}
- try {
- if (bindings != null) {
- bindings.forEach(compiler::set);
- }
- PyObject out = compiler.eval(code);
- if (out != null) {
- String value = out.toString();
- return
getCamelContext().getTypeConverter().convertTo(resultType, value);
+ // the interpreter is shared by every caller of this method: bind, run
and clean up under one lock
+ synchronized (compiler) {
Review Comment:
**The compile a few lines above this is on the same shared interpreter, but
outside the lock.**
`PythonInterpreter.compile(Reader, String)` is not a pure function of its
argument — it reads `this.cflags`, passes that same mutable `CompilerFlags`
instance into `ParserFacade.parseExpressionOrModule(...)` (which writes back
any `from __future__` flags it finds), and then calls `setSystemState()`, which
installs this interpreter's `PySystemState` as the *thread's* current one.
So two threads missing the cache on different scripts mutate one
`CompilerFlags`, and a compiling thread races the `setSystemState()`/`eval` of
a thread already inside this `synchronized` block. Same
shared-mutable-interpreter race the PR fixes on the evaluation path, just on
the compile path.
Pulling the cache miss inside the lock closes it and also makes the
double-checked lookup honest:
```java
synchronized (compiler) {
PyCode code = getCompiledScriptFromCache(script);
if (code == null) {
try {
code = compiler.compile(script);
addCompiledScriptToCache(script, code);
} catch (Exception e) {
throw new ExpressionIllegalSyntaxException(script, e);
}
}
try {
...
```
(`PythonExpression`'s constructor compiles against its own private
interpreter before the expression is published, so that one is fine as-is.)
--
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]