allthingssecurity commented on code in PR #27793:
URL: https://github.com/apache/camel/pull/27793#discussion_r4267170128


##########
components/camel-wasm/src/main/java/org/apache/camel/component/wasm/WasmEndpoint.java:
##########
@@ -63,6 +75,44 @@ public WasmConfiguration getConfiguration() {
         return configuration;
     }
 
+    /**
+     * The module of this endpoint as a command. The module is loaded, checked 
and, with compile=true, compiled on the
+     * first call, by the first producer that is initialized; all producers of 
the endpoint then share the result, which
+     * is immutable, for as long as the endpoint exists. So a route that is 
stopped and started again gets a new
+     * producer, but neither loads nor compiles the module again, and the 
classes generated for a compiled module can
+     * only be unloaded when the endpoint is no longer reachable (removed from 
the context, or the context stopped), not
+     * when a route stops.
+     * <p/>
+     * A failed call leaves nothing behind, so the next call (of the next 
producer that is initialized) tries again.
+     */
+    WasiCommand command() throws Exception {
+        WasiCommand answer = command;
+        if (answer == null) {
+            lock.lock();
+            try {
+                answer = command;
+                if (answer == null) {
+                    List<String> arguments
+                            = 
WasmProducer.arguments(WasmProducer.programName(module), 
configuration.getArgs());

Review Comment:
   Done in 0a6a9c226b4d: `programName`, `arguments` and `checkNoNul` (with 
`DEFAULT_PROGRAM_NAME`) moved from `WasmProducer`
   to `WasmEndpoint`, static with package access. `WasmProducer` calls 
`WasmEndpoint.checkNoNul` for the environment
   variables and headers; the tests that called 
`WasmProducer.programName`/`arguments` call the endpoint now. No
   behaviour change. camel-wasm: 132 run, 0 failures.
   
   _Claude Code on behalf of allthingssecurity_



##########
docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc:
##########
@@ -111,6 +111,12 @@ module.
 * `WasmSupport.deserialize(byte[], Exchange)`.
 * The constructor `WasmProducer(Endpoint, String, String)` is replaced by 
`WasmProducer(WasmEndpoint)`.
 
+The endpoint has a new `compile` option (default `false`) that runs a module 
as JVM bytecode instead of interpreting
+it. For this option `camel-wasm` has a new dependency, `run.endive:compiler`, 
which brings in ASM (`org.ow2.asm`).
+The module is now loaded once per endpoint and no longer by every producer, so 
stopping and starting a route does
+not read the module again: remove the route and add it again, or restart the 
application, to load a module that
+has changed.

Review Comment:
   Applied your wording in 0a6a9c226b4d: the paragraph now starts with the new 
dependency, then the `compile` option, then
   the loading change.
   
   _Claude Code on behalf of allthingssecurity_



##########
components/camel-wasm/pom.xml:
##########
@@ -54,6 +54,12 @@
             <artifactId>wasi</artifactId>
             <version>${endive-version}</version>
         </dependency>
+        <!-- used with compile=true only: translates a module to JVM bytecode, 
once per endpoint -->
+        <dependency>
+            <groupId>run.endive</groupId>
+            <artifactId>compiler</artifactId>
+            <version>${endive-version}</version>
+        </dependency>

Review Comment:
   davsclaus decided this in his review: `run.endive:compiler` stays a normal 
dependency (optional dependencies need
   extra steps with `camel run`, the Spring Boot starter and Camel Quarkus, and 
the compiler is already in the SBOM through
   camel-opa). The pom is unchanged, and the open question is removed from the 
description.
   
   _Claude Code on behalf of allthingssecurity_



##########
components/camel-wasm/src/main/java/org/apache/camel/wasm/WasiCommand.java:
##########
@@ -73,10 +91,77 @@ public final class WasiCommand {
      *                                  than the initial memory the module 
declares
      */
     public WasiCommand(WasmModule module, List<String> arguments, int 
maxMemoryPages) {
+        this(module, arguments, maxMemoryPages, false);
+    }
+
+    /**
+     * @param  module                   the parsed module
+     * @param  arguments                the program's arguments, the program 
name first
+     * @param  maxMemoryPages           the maximum number of 64 KiB pages the 
module's memory may grow to, or 0 to keep
+     *                                  the maximum the module declares
+     * @param  compile                  whether to translate the module to JVM 
bytecode now, with the Endive runtime
+     *                                  compiler, instead of interpreting it. 
This defines classes at run time, which a
+     *                                  GraalVM native image cannot do. A 
function that is too large for a JVM method is
+     *                                  left to the interpreter, which is 
logged once, at WARN
+     * @throws IllegalArgumentException if the module is not a WASI Preview 1 
command module, or maxMemoryPages is lower
+     *                                  than the initial memory the module 
declares
+     * @throws IllegalStateException    if compile is set and the Endive 
runtime compiler is not on the classpath, or
+     *                                  cannot compile the module. The message 
names the module by its program name (the
+     *                                  first argument)
+     */
+    public WasiCommand(WasmModule module, List<String> arguments, int 
maxMemoryPages, boolean compile) {
         this.module = Objects.requireNonNull(module);
         this.arguments = List.copyOf(arguments);
         validate(module);
         this.memoryLimits = memoryLimits(module, maxMemoryPages);
+
+        Function<Instance, Machine> factory = null;
+        boolean fallback = false;
+        if (compile) {
+            String name = this.arguments.isEmpty() ? "(no name)" : 
this.arguments.get(0);
+            try {
+                try {
+                    factory = RuntimeCompiler.compile(module, false);
+                } catch (WasmEngineException e) {
+                    // Endive could not compile every function. When the 
reason is a function that is too large for a
+                    // JVM method, the module still works with that function 
interpreted, so compile again with the
+                    // interpreter as fallback; for any other reason this 
second attempt fails as the first one did.
+                    factory = RuntimeCompiler.compile(module, true);
+                    fallback = true;
+                    LOG.warn("The Wasm module {} is compiled in part only: it 
has functions that are too large for a"

Review Comment:
   davsclaus answered question 3 in his review: the current handling (`FAIL`, 
then `SILENT` with one log line) is fine.
   So the line stays at WARN, logged once per endpoint, and the open question 
is removed from the description.
   
   _Claude Code on behalf of allthingssecurity_



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to