[
https://issues.apache.org/jira/browse/CAMEL-25606?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Claus Ibsen resolved CAMEL-25606.
---------------------------------
Resolution: Fixed
> camel-wasm - Optional runtime compiler for the wasm endpoint (compile=true,
> module loaded and compiled once per endpoint)
> -------------------------------------------------------------------------------------------------------------------------
>
> Key: CAMEL-25606
> URL: https://issues.apache.org/jira/browse/CAMEL-25606
> Project: Camel
> Issue Type: Improvement
> Reporter: shashank
> Assignee: shashank
> Priority: Major
> Fix For: 4.24.0
>
>
> Since CAMEL-25531 the {{wasm}} endpoint runs WASI Preview 1 command modules,
> one new instance per exchange, with the Endive interpreter. The interpreter
> is slow for modules that compute a lot per message or have a large runtime
> (standard Go programs). Endive has a runtime compiler that translates a
> module to JVM bytecode. This ticket makes it available as an endpoint option.
> h3. The option
> * {{compile}} (boolean, endpoint option, default {{false}}). With
> {{compile=true}} the module is translated to JVM bytecode with
> {{run.endive.compiler.MachineFactoryCompiler}} instead of being interpreted.
> * Default off, because compiling costs start-up time and generates classes at
> run time, which a GraalVM native image cannot load.
> * Everything else is the same with the compiler on: result headers, exit
> codes, traps, {{maxMemoryPages}}, {{maxOutputSize}}, environment and
> arguments, {{SecureRandom}} for {{random_get}}, {{timeout}} (compiled code
> checks the thread interrupt like the interpreter), the body read on the
> calling thread when a timeout is set, streams opened by the type converter
> closed, the body after a failed run. The option gives a module no new
> capability.
> * New dependency of camel-wasm: {{run.endive:compiler}} (Apache-2.0, 163 KB),
> which brings ASM in the version Camel already manages.
> * New public API: {{WasmConfiguration.isCompile/setCompile}},
> {{WasiCommand(WasmModule, List<String>, int, boolean)}},
> {{WasiCommand.isCompiled()}}. The three-argument constructor is kept.
> h3. When the module is loaded and compiled
> * Once per endpoint, when the first producer of the endpoint is initialized:
> when the route is first started, or at the first message with
> {{lazyStartProducer=true}} or {{toD}}. {{WasmEndpoint}} keeps one immutable
> {{WasiCommand}} for as long as it exists, and all its producers share it.
> Exchanges still run on separate instances; they share only the generated
> classes.
> * With CAMEL-25531 every producer parsed the module itself, and a route start
> creates a new producer, so a compiler in the producer would compile the same
> module at every route start. With this change a route stop and start neither
> reads nor compiles the module again. A changed module file is read by a new
> endpoint only (route removed and added again, application restarted).
> * The generated classes can be unloaded when the endpoint is no longer
> reachable, not when a route stops. A route reload in development mode removes
> all routes and endpoints by default, so it reads and compiles the module
> again.
> * With a dynamic endpoint ({{toD}}) every different URI is an endpoint with
> its own compiled copy of the module, so many different compiled URIs make
> metaspace grow. The component page says so.
> * A failed load is not kept: the next producer that is initialized tries
> again.
> h3. Failure modes
> * A function that is too large for a JVM method is left to the interpreter
> and the rest of the module is compiled. Endive reports that on {{System.err}}
> by default ({{InterpreterFallback.WARN}}). The component compiles with
> {{FAIL}} first and, when that fails, again with {{SILENT}}, and logs once per
> endpoint at WARN with the name of the module; nothing is written to
> {{System.err}}.
> * A module the compiler cannot translate fails when the first producer is
> initialized, with an {{IllegalStateException}} that names the module by its
> file name and has the Endive exception as cause.
> * {{WasiCommand}} refers to the compiler through one nested class, so it
> still loads and interprets when {{run.endive:compiler}} is excluded from the
> classpath; {{compile=true}} then fails with an {{IllegalStateException}} that
> names the artifact.
> h3. Docs
> * Component page, section Performance: the option, when the module is
> compiled, when to keep the default. No numbers.
> * Upgrade guide 4.24: one paragraph in the existing camel-wasm section (the
> option, the new dependency, the module loaded once per endpoint).
> h3. Tests
> * camel-wasm: 132 tests, 0 failures. {{WasmCompiledComponentTest}} extends
> {{WasmComponentTest}} and runs all its 58 tests with {{compile=true}}; no
> test behaves differently with the compiler on.
> * New tests: the second producer of an endpoint gets the same command without
> reading the module again; a route stop and start keeps the command; a load
> that failed is tried again by the next producer; a trap shows generated
> classes with {{compile=true}} and interpreter frames without; a function that
> is too large is interpreted, the module runs and nothing is printed to
> {{System.err}}; a module that cannot be compiled fails with its name;
> {{compile=true}} without the compiler on the classpath fails with the name of
> the artifact.
> h3. Not run
> * A GraalVM native image (neither that {{compile=true}} fails there nor that
> the interpreter works there).
> * The full build from the root.
> * A route reload in development mode with a compiled module, and a metaspace
> measurement with {{toD}}.
> * Performance on the final change: earlier measurements through a route (one
> machine, an earlier state of the CAMEL-25531 work) showed compiled modules 5
> to 150 times faster per exchange and a first start of up to about a second
> for a 2.3 MB Go program; they are indicative only and are in the pull request.
> h3. Open questions for the pull request
> * {{run.endive:compiler}} as a normal dependency (proposed, about 0.55 MB
> with ASM) or an optional one (which needs {{--dep}} with {{camel run}}).
> * A hook for modules compiled at build time with the Endive Maven plugin (the
> native-image friendly way); not part of this ticket.
> * The handling of functions that are too large: fallback to the interpreter
> with a WARN (proposed), silent fallback, or failure.
> * The module is now loaded by the endpoint and kept as long as the endpoint
> exists.
> _Filed with Claude Code on behalf of allthingssecurity._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)