Federico Mariani created CAMEL-24688:
----------------------------------------

             Summary: camel-quickjs - controlled camel API, variables/exception 
bindings, compile each script once per engine
                 Key: CAMEL-24688
                 URL: https://issues.apache.org/jira/browse/CAMEL-24688
             Project: Camel
          Issue Type: Improvement
    Affects Versions: 4.23.0
            Reporter: Federico Mariani


Follow-up to the review discussion on apache/camel#25778 (parity with 
camel-javascript within the JSON-only security model: read and mutate 
headers/properties/body from a script, call a controlled Camel API).

Proposed (implemented, 55 tests, benchmarked):
* a frozen {{camel}} facade backed by QuickJS4J host functions in a {{camel}} 
builtins module: {{getBody/setBody}}, {{get/set/removeHeader}}, 
{{get/set/removeProperty}}, {{get/set/removeVariable}}, {{log(level, 
message)}}. The facade captures the real {{java_invoke}} in a closure scripts 
cannot reach and only dispatches to that module with a fixed arity per 
function; {{java_invoke}}, {{quickjs4j_engine}} and {{camelQuickjs}} stay 
stubbed on {{globalThis}} while a script runs, as today. The current exchange 
is held per thread (engines are per thread), so the API is only available to 
route expressions, not to the generic {{ScriptingLanguage.evaluate}}.
* new bindings {{variables}} (exchange variables) and {{exception}} ({{{type, 
message}}} or null).
* route scripts compiled once per engine instead of {{new Function}} + {{eval}} 
on every evaluation: the script is embedded in the guest library (as {{return 
(script)}} when it is a single expression, through {{eval}} otherwise so 
statement scripts keep their completion value), compiled with 
{{compilePortableGuestFunction}} and run with 
{{invokePrecompiledGuestFunction}}; a bounded LRU of 1,000 compiled scripts per 
engine replaces the engine's unbounded SHA-256 cache.
* syntax errors in statement scripts reported as 
{{ExpressionIllegalSyntaxException}} at compile time; a script that throws 
discards the thread's engine, because the QuickJS runtime panics ("RefCell 
already borrowed") on its next compile otherwise.

Measured: expressions 1.7k -> 3.9k ops/s (2.3x), route 843 -> 1,848 msg/s on 
one thread and 5,346 -> 10,411 on eight; still far below the JVM-compiled 
languages, which is the JSON snapshot per evaluation. Docs and the catalog 
mirror updated (variables table, {{camel}} API, expression/statement rule, 
engine lifecycle).

Related: CAMEL-23398.

----
_Found during a benchmark review of camel-groovy and the other scripting 
languages (camel-performance-tests branch camel-groovy-perf, 
tests/camel-jmh/groovy-results, JMH 1.37, JDK 21, one M1 Pro laptop). A 
candidate fix with tests exists on the local apache/camel branch 
camel-perf-all-fixes; a PR follows._

_Claude Code on behalf of Croway_



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to