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/16 09:00:00 UTC

[jira] [Resolved] (CAMEL-24689) camel-javascript - share one GraalJS Engine per language and cache the parsed Source; do not silence the interpreter-only warning

     [ https://issues.apache.org/jira/browse/CAMEL-24689?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Federico Mariani resolved CAMEL-24689.
--------------------------------------
    Resolution: Fixed

> camel-javascript - share one GraalJS Engine per language and cache the parsed Source; do not silence the interpreter-only warning
> ---------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-24689
>                 URL: https://issues.apache.org/jira/browse/CAMEL-24689
>             Project: Camel
>          Issue Type: Improvement
>    Affects Versions: 4.22.0
>            Reporter: Federico Mariani
>            Assignee: Federico Mariani
>            Priority: Major
>             Fix For: 4.23.0
>
>
> {{JavaScriptHelper.newContext()}} builds a GraalJS {{Context}} without a shared {{Engine}}, so every evaluation creates a private engine, re-parses the script and allocates ~860 KB; {{JavaScriptExpression}} also rebuilds the {{Source}} every time. Measured on main: 3,120 ops/s for {{body + '-' + headers.get('foo')}} and 1.7 MB allocated per route message. Both camel-javascript and camel-python3 set {{engine.WarnInterpreterOnly=false}}, so users never learn the engine runs interpreted on a stock JDK.
> Proposed fix (implemented, tested, benchmarked), following the camel-python3 pattern: {{JavaScriptLanguage}} becomes a {{Service}} owning one lazily created {{Engine}} (closed on stop), contexts are still created per evaluation but with {{.engine(shared)}} and the same access options, the {{Source}} is cached per script text (LRU soft cache), one INFO line at engine creation reports interpreted mode, and JS objects/arrays/Map/Set/Date returned by a script are materialized before the {{Context}} closes (on main {{o.as(Object.class)}} returned proxies bound to a closed context, which threw on first access).
> Measured: expressions 1.8x, 1-thread route 1.8x, 8-thread 5-minute load 4,697 -> 15,006 msg/s (3.2x) with 1.77 MB -> 323 KB per message. One open reading to look at before merging: the 8-thread JMH route read 0.67x with the shared engine (p99 2.7 -> 4.8 ms), so the shared engine serialises something under concurrency in interpreted mode.
> Related: CAMEL-18718 (GraalJS language), CAMEL-24337 (python3 pattern), CAMEL-24467 (bindings).
> ----
> _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)