This is an automated email from the ASF dual-hosted git repository.

apkhmv pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git


The following commit(s) were added to refs/heads/main by this push:
     new b88e8eaa86a IGNITE-27530 Optimize CLI startup time for non-interactive 
commands (#7382)
b88e8eaa86a is described below

commit b88e8eaa86a181db6045409551700713a58cf3c6
Author: Aleksandr Pakhomov <[email protected]>
AuthorDate: Tue Jan 13 13:44:23 2026 +0300

    IGNITE-27530 Optimize CLI startup time for non-interactive commands (#7382)
    
    Co-authored-by: Claude Opus 4.5 <[email protected]>
---
 CLAUDE.md                                          |  8 ++++++
 .../java/org/apache/ignite/internal/cli/Main.java  | 32 ++++++++++++++++------
 .../cli/commands/connect/ConnectCommand.java       |  4 ++-
 packaging/cli/build.gradle                         |  8 +++++-
 packaging/cli/start.sh                             |  3 ++
 5 files changed, 44 insertions(+), 11 deletions(-)

diff --git a/CLAUDE.md b/CLAUDE.md
index eb3496617b3..972fe4bc91b 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -106,6 +106,14 @@ Run checkstyle and PMD on the modified module(s):
 ./gradlew :ignite-<module>:checkstyleMain :ignite-<module>:checkstyleTest 
:ignite-<module>:pmdMain :ignite-<module>:pmdTest
 ```
 
+Run IDEA inspections on the modified module(s):
+```bash
+idea inspect . .idea/inspectionProfiles/Project_Default.xml /tmp/results -d 
modules/<module>
+```
+Notes:
+- IntelliJ IDEA must be closed for command-line inspections to work.
+- If `idea` command is not available, ask the user to install it via: **Tools 
> Create Command-line Launcher** in IntelliJ IDEA.
+
 ### Git Push
 **Never use `git push` without specifying the target branch.** Always push 
explicitly:
 ```bash
diff --git a/modules/cli/src/main/java/org/apache/ignite/internal/cli/Main.java 
b/modules/cli/src/main/java/org/apache/ignite/internal/cli/Main.java
index 7ab70ad6f18..5625b842840 100644
--- a/modules/cli/src/main/java/org/apache/ignite/internal/cli/Main.java
+++ b/modules/cli/src/main/java/org/apache/ignite/internal/cli/Main.java
@@ -53,25 +53,39 @@ public class Main {
     public static void main(String[] args) {
         initJavaLoggerProps();
 
+        // Determine if we're entering interactive REPL mode.
+        // REPL mode is only entered when no args AND stdin/stdout are 
terminals.
+        boolean interactiveMode = args.length == 0 && isatty();
+
         int exitCode = 0;
         ApplicationContextBuilder builder = 
ApplicationContext.builder(Environment.CLI).deduceEnvironment(false);
         try (MicronautFactory micronautFactory = new 
MicronautFactory(builder.start())) {
-            AnsiConsole.systemInstall();
-            initReplExecutor(micronautFactory);
-            initQuestionAsker(micronautFactory);
-            if (args.length != 0 || !isatty()) { // do not enter REPL if input 
or output is redirected
+            if (interactiveMode) {
+                // REPL mode: full initialization with Jansi ANSI console and 
JLine terminal.
+                AnsiConsole.systemInstall();
+                initReplExecutor(micronautFactory);
+                initQuestionAsker(micronautFactory);
+                enterRepl(micronautFactory);
+            } else {
+                // Non-interactive mode: skip JLine terminal initialization 
for faster startup.
+                // Only install ANSI console if stdout is a terminal (for 
colored output).
+                if (isatty()) {
+                    AnsiConsole.systemInstall();
+                }
                 try {
                     exitCode = executeCommand(args, micronautFactory);
                 } catch (Exception e) {
-                    System.err.println("Error occurred during command 
execution");
+                    System.err.println("Error occurred during command 
execution: " + e.getMessage());
+                    exitCode = 1;
                 }
-            } else {
-                enterRepl(micronautFactory);
             }
         } catch (Exception e) {
-            System.err.println("Error occurred during initialization");
+            System.err.println("Error occurred during initialization: " + 
e.getMessage());
+            exitCode = 1;
         } finally {
-            AnsiConsole.systemUninstall();
+            if (AnsiConsole.isInstalled()) {
+                AnsiConsole.systemUninstall();
+            }
         }
         System.exit(exitCode);
     }
diff --git 
a/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/connect/ConnectCommand.java
 
b/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/connect/ConnectCommand.java
index 0cc8e01fad3..055ed7be933 100644
--- 
a/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/connect/ConnectCommand.java
+++ 
b/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/connect/ConnectCommand.java
@@ -21,6 +21,7 @@ import static 
org.apache.ignite.internal.cli.commands.Options.Constants.CLUSTER_
 import static 
org.apache.ignite.internal.cli.commands.Options.Constants.NODE_URL_OPTION_DESC;
 
 import jakarta.inject.Inject;
+import jakarta.inject.Provider;
 import java.net.URL;
 import java.util.concurrent.Callable;
 import org.apache.ignite.internal.cli.ReplManager;
@@ -50,11 +51,12 @@ public class ConnectCommand extends BaseCommand implements 
Callable<Integer> {
     private ConnectWizardCall connectCall;
 
     @Inject
-    private ReplManager replManager;
+    private Provider<ReplManager> replManagerProvider;
 
     /** {@inheritDoc} */
     @Override
     public Integer call() {
+        ReplManager replManager = replManagerProvider.get();
         // We need to do this before the connect call since it will fire 
events even before repl start.
         replManager.subscribe();
 
diff --git a/packaging/cli/build.gradle b/packaging/cli/build.gradle
index d84feda4ac1..835a414ccd6 100644
--- a/packaging/cli/build.gradle
+++ b/packaging/cli/build.gradle
@@ -84,7 +84,13 @@ def cliStartScript = tasks.register('cliStartScript', 
CreateStartScripts) {
     classpath = files(new File("../lib/*"))
     outputDir = file "$buildDir/scripts"
     applicationName = 'ignite3'
-    defaultJvmOpts += ['--add-opens=java.base/java.lang=ALL-UNNAMED', 
'-Xmx256m']
+    defaultJvmOpts += [
+        '--add-opens=java.base/java.lang=ALL-UNNAMED',
+        '--enable-native-access=ALL-UNNAMED',
+        '-Xmx256m',
+        '-XX:TieredStopAtLevel=1',
+        '-XX:+UseSerialGC'
+    ]
 }
 
 def windowsCliStartScript = tasks.register('windowsCliStartScript', Copy) {
diff --git a/packaging/cli/start.sh b/packaging/cli/start.sh
index d5085c35f59..dce73fc8ca8 100644
--- a/packaging/cli/start.sh
+++ b/packaging/cli/start.sh
@@ -25,7 +25,10 @@ MAIN_CLASS="@MAIN_CLASS@"
 
 DEFAULT_JVM_OPTS="-Dfile.encoding=UTF-8 \
     --add-opens=java.base/java.lang=ALL-UNNAMED \
+    --enable-native-access=ALL-UNNAMED \
     -Xmx256m \
+    -XX:TieredStopAtLevel=1 \
+    -XX:+UseSerialGC \
     -XX:+HeapDumpOnOutOfMemoryError \
     -XX:+ExitOnOutOfMemoryError \
     -XX:HeapDumpPath=${LOG_DIR}"

Reply via email to