You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@camel.apache.org by "Federico Mariani (Jira)" <ji...@apache.org> on 2026/09/11 08:30:00 UTC

[jira] [Created] (CAMEL-24688) camel-quickjs - controlled camel API, variables/exception bindings, compile each script once per engine

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)