fix: synchronize GraalVM JavaScript context access in JavaScriptTieredBrokerSelectorStrategy (#18253) [fj4WqyCCw3C5ShR1RfB7MoBPTpkRrBFYP1uT35g3MvT] - #19856
Conversation
…dBrokerSelectorStrategy (apache#18253)
FrankChen021
left a comment
There was a problem hiding this comment.
I have reviewed the code for correctness, edge cases, concurrency, and integration risks; no issues found.
Reviewed 1 of 1 changed files.
This is an automated review by Codex GPT-5.6-Sol
|
|
||
| @Override | ||
| public Optional<String> getBrokerServiceName(TieredBrokerConfig config, Query query) | ||
| public synchronized Optional<String> getBrokerServiceName(TieredBrokerConfig config, Query query) |
There was a problem hiding this comment.
Although Codex reports 'LGTM', I have different opinons.
If you look at the usage of compileSelectorFunction, there's another place that uses it, and the 'synchronized' is not added. So adding 'synchronized' to caller is not good, we may forget to add it in new places.
As this is due to script engine layer problem, I think it's the compileSelectorFunction that ensures that the returned fnSelector is a concurrent safe version.
One way is that we can use dynamic proxy inside compileSelectorFunction to wrap existing object and forward the call in a synchronized block
|
I think we should honestly remove JS support for the next release – wdyt @kfaraz @clintropolis @gianm? The JS functionality has long been source of bugs/CVEs, etc. and is, IMO, not worth keeping in core Druid (perhaps as an extension). |
Fixes #18253
Problem
GraalVM JS engine throws
IllegalStateException: Multi threaded access requestedwhen the same JavaScript context is accessed from multiple threads simultaneously. TheJavaScriptTieredBrokerSelectorStrategyshares a single compiled JavaScript function across all broker routing threads, which triggers this error.Root cause
JavaScriptUtil.compileSelectorFunction()creates a GraalVMScriptEnginethat is not thread-safe. ThefnSelectorfield is lazily initialized with a non-atomic check-then-write pattern, andfnSelector.apply()is called from multiple Jetty handler threads without synchronization.Fix
synchronizedtogetBrokerServiceName()to serialize all access to the shared GraalVM contextTesting
Multi threaded access requestederror in production Router deploymentsCC: @jtuglu1