Copilot commented on code in PR #17181:
URL: https://github.com/apache/iotdb/pull/17181#discussion_r2815541545


##########
iotdb-client/cli/src/main/java/org/apache/iotdb/cli/Cli.java:
##########
@@ -188,41 +239,104 @@ private static void executeSql(CliContext ctx) throws 
TException {
       processCommand(ctx, execute, connection);
       ctx.exit(lastProcessStatus);
     } catch (SQLException e) {
-      ctx.getPrinter().println(IOTDB_ERROR_PREFIX + "Can't execute sql 
because" + e.getMessage());
+      ctx.getPrinter()
+          .println(IOTDB_ERROR_PREFIX + ": Can't execute sql because " + 
e.getMessage());
       ctx.exit(CODE_ERROR);
     }
   }
 
   private static void receiveCommands(CliContext ctx) throws TException {
-    try (IoTDBConnection connection =
-        (IoTDBConnection)
-            DriverManager.getConnection(Config.IOTDB_URL_PREFIX + host + ":" + 
port + "/", info)) {
-      connection.setQueryTimeout(queryTimeout);
-      properties = connection.getServerProperties();
-      timestampPrecision = properties.getTimestampPrecision();
-
+    IoTDBConnection connection = null;
+    try {
+      connection = openConnection();
+      setupConnection(connection);
       echoStarting(ctx);
       displayLogo(ctx, properties.getLogo(), properties.getVersion(), 
properties.getBuildInfo());
       ctx.getPrinter().println(String.format("Successfully login at %s:%s", 
host, port));
       while (true) {
-        boolean readLine = readerReadLine(ctx, connection);
-        if (readLine) {
+        ReadLineResult result = readerReadLine(ctx, connection);
+        if (result.stop) {
           break;
         }
+        if (result.failedCommand != null) {
+          // Connection failed during processCommand; try to reconnect and 
retry the command.
+          closeConnectionQuietly(connection);
+          connection = null;
+          boolean reconnected = false;
+          for (int attempt = 1; attempt <= RECONNECT_RETRY_NUM; attempt++) {
+            if (attempt > 1) {
+              try {
+                Thread.sleep(RECONNECT_RETRY_INTERVAL_MS);
+              } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+                ctx.getErr().printf("%s: Reconnection interrupted.%n", 
IOTDB_ERROR_PREFIX);
+                ctx.exit(CODE_ERROR);
+              }
+            }
+            try {
+              connection = openConnection();
+              setupConnection(connection);
+              ctx.getPrinter().println("Connection lost. Reconnected. Retrying 
command.");
+              processCommand(ctx, result.failedCommand, connection);
+              reconnected = true;
+              break;
+            } catch (SQLException e) {
+              if (isSessionOrStatementError(e)) {
+                // Reconnect succeeded but retry failed due to 
session/statement state; ask user to
+                // run the command again.
+                ctx.getPrinter()
+                    .println(
+                        "Reconnected, but the previous command could not be 
completed. Please run your command again.");
+                reconnected = true;
+                break;
+              }
+              if (attempt == RECONNECT_RETRY_NUM) {
+                ctx.getErr()
+                    .printf(
+                        "%s: Could not reconnect after %d attempts. Please 
check that the server is running and try again.%n",
+                        IOTDB_ERROR_PREFIX, RECONNECT_RETRY_NUM);
+                ctx.exit(CODE_ERROR);
+              }
+            } catch (TException e) {
+              // RPC/network failure during reconnect (e.g. 
getServerProperties); treat as reconnect
+              // failure and retry with backoff.
+              if (attempt == RECONNECT_RETRY_NUM) {
+                ctx.getErr()
+                    .printf(
+                        "%s: Could not reconnect after %d attempts. Please 
check that the server is running and try again.%n",
+                        IOTDB_ERROR_PREFIX, RECONNECT_RETRY_NUM);
+                ctx.exit(CODE_ERROR);
+              }
+            }
+          }
+          if (!reconnected) {
+            break;
+          }
+        }
       }
     } catch (SQLException e) {
       ctx.getErr().printf("%s: %s%n", IOTDB_ERROR_PREFIX, e.getMessage());
       ctx.exit(CODE_ERROR);
+    } finally {
+      closeConnectionQuietly(connection);
     }
   }
 
-  private static boolean readerReadLine(CliContext ctx, IoTDBConnection 
connection) {
+  private static ReadLineResult readerReadLine(CliContext ctx, IoTDBConnection 
connection) {
     String s;
     try {
       s = ctx.getLineReader().readLine(cliPrefix + "> ", null);
-      boolean continues = processCommand(ctx, s, connection);
-      if (!continues) {
-        return true;
+      try {
+        boolean continues = processCommand(ctx, s, connection);
+        if (!continues) {
+          return ReadLineResult.stopLoop();
+        }
+      } catch (SQLException e) {
+        if (isConnectionRelated(e)) {
+          return ReadLineResult.reconnectAndRetry(s);
+        }

Review Comment:
   On connection-related failure, the CLI retries the entire raw line `s` 
(`reconnectAndRetry(s)`). Because `processCommand` can execute multiple 
`;`-separated statements, a failure on a later statement will cause earlier 
statements in the same line to be re-executed after reconnect (risking 
duplicate inserts/DDL). Consider tracking and retrying only the specific 
statement that failed (or disable auto-retry when multiple statements are 
present and instead prompt the user to re-run).



-- 
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