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

rong pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/master by this push:
     new b0cfead5f3b Pipe: Fixed the deadlock cause by terminate event 
reporting & Added sink.batch.max-delay-ms to enable delicate control over batch 
delay & Fixed the bug of premature halt in extractor snapshot mode cause by 
real-time-first transfer & Stabilized the trigger of default batch sending & 
Added "isNeedToReport" getter in PipeRawTabletInsertionEvent for user-defined 
plugins & Reduce logs from PipeEventCommitter (#15377)
b0cfead5f3b is described below

commit b0cfead5f3b411bb5a3a194c74ec90cdbf974b7c
Author: Caideyipi <[email protected]>
AuthorDate: Wed Apr 23 10:19:12 2025 +0800

    Pipe: Fixed the deadlock cause by terminate event reporting & Added 
sink.batch.max-delay-ms to enable delicate control over batch delay & Fixed the 
bug of premature halt in extractor snapshot mode cause by real-time-first 
transfer & Stabilized the trigger of default batch sending & Added 
"isNeedToReport" getter in PipeRawTabletInsertionEvent for user-defined plugins 
& Reduce logs from PipeEventCommitter (#15377)
    
    Co-authored-by: Steve Yurong Su <[email protected]>
---
 .../task/builder/PipeDataNodeTaskBuilder.java      | 51 +++++++++++++++++++---
 .../subtask/connector/PipeConnectorSubtask.java    | 13 +++---
 .../batch/PipeTransferBatchReqBuilder.java         | 40 ++++++++---------
 .../PipeConsensusTransferBatchReqBuilder.java      | 19 +++++---
 .../common/tablet/PipeRawTabletInsertionEvent.java |  5 +++
 .../event/common/terminate/PipeTerminateEvent.java |  6 ++-
 ...oricalDataRegionTsFileAndDeletionExtractor.java | 30 +------------
 .../agent/task/progress/PipeEventCommitter.java    | 28 ++++++------
 .../config/constant/PipeConnectorConstant.java     |  3 ++
 .../pipe/connector/protocol/IoTDBConnector.java    | 10 +++++
 10 files changed, 125 insertions(+), 80 deletions(-)

diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/agent/task/builder/PipeDataNodeTaskBuilder.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/agent/task/builder/PipeDataNodeTaskBuilder.java
index 1b517419c98..5be9dc8ab64 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/agent/task/builder/PipeDataNodeTaskBuilder.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/agent/task/builder/PipeDataNodeTaskBuilder.java
@@ -51,6 +51,14 @@ import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstan
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.CONNECTOR_FORMAT_TABLET_VALUE;
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.CONNECTOR_FORMAT_TS_FILE_VALUE;
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.SINK_FORMAT_KEY;
+import static 
org.apache.iotdb.commons.pipe.config.constant.PipeExtractorConstant.EXTRACTOR_MODE_DEFAULT_VALUE;
+import static 
org.apache.iotdb.commons.pipe.config.constant.PipeExtractorConstant.EXTRACTOR_MODE_KEY;
+import static 
org.apache.iotdb.commons.pipe.config.constant.PipeExtractorConstant.EXTRACTOR_MODE_QUERY_VALUE;
+import static 
org.apache.iotdb.commons.pipe.config.constant.PipeExtractorConstant.EXTRACTOR_MODE_SNAPSHOT_DEFAULT_VALUE;
+import static 
org.apache.iotdb.commons.pipe.config.constant.PipeExtractorConstant.EXTRACTOR_MODE_SNAPSHOT_KEY;
+import static 
org.apache.iotdb.commons.pipe.config.constant.PipeExtractorConstant.EXTRACTOR_MODE_SNAPSHOT_VALUE;
+import static 
org.apache.iotdb.commons.pipe.config.constant.PipeExtractorConstant.SOURCE_MODE_KEY;
+import static 
org.apache.iotdb.commons.pipe.config.constant.PipeExtractorConstant.SOURCE_MODE_SNAPSHOT_KEY;
 
 public class PipeDataNodeTaskBuilder {
 
@@ -171,14 +179,33 @@ public class PipeDataNodeTaskBuilder {
 
   private void checkConflict(
       final PipeParameters extractorParameters, final PipeParameters 
connectorParameters) {
+    final Pair<Boolean, Boolean> insertionDeletionListeningOptionPair;
+    final boolean shouldTerminatePipeOnAllHistoricalEventsConsumed;
 
     try {
-      final Pair<Boolean, Boolean> insertionDeletionListeningOptionPair =
+      insertionDeletionListeningOptionPair =
           
DataRegionListeningFilter.parseInsertionDeletionListeningOptionPair(extractorParameters);
-      if (!insertionDeletionListeningOptionPair.right) {
+
+      if (extractorParameters.hasAnyAttributes(
+          EXTRACTOR_MODE_SNAPSHOT_KEY, SOURCE_MODE_SNAPSHOT_KEY)) {
+        shouldTerminatePipeOnAllHistoricalEventsConsumed =
+            extractorParameters.getBooleanOrDefault(
+                Arrays.asList(EXTRACTOR_MODE_SNAPSHOT_KEY, 
SOURCE_MODE_SNAPSHOT_KEY),
+                EXTRACTOR_MODE_SNAPSHOT_DEFAULT_VALUE);
+      } else {
+        final String extractorModeValue =
+            extractorParameters.getStringOrDefault(
+                Arrays.asList(EXTRACTOR_MODE_KEY, SOURCE_MODE_KEY), 
EXTRACTOR_MODE_DEFAULT_VALUE);
+        shouldTerminatePipeOnAllHistoricalEventsConsumed =
+            extractorModeValue.equalsIgnoreCase(EXTRACTOR_MODE_SNAPSHOT_VALUE)
+                || 
extractorModeValue.equalsIgnoreCase(EXTRACTOR_MODE_QUERY_VALUE);
+      }
+
+      if (!insertionDeletionListeningOptionPair.right
+          && !shouldTerminatePipeOnAllHistoricalEventsConsumed) {
         return;
       }
-    } catch (IllegalPathException e) {
+    } catch (final IllegalPathException e) {
       LOGGER.warn(
           "PipeDataNodeTaskBuilder failed to parse 'inclusion' and 'exclusion' 
parameters: {}",
           e.getMessage(),
@@ -192,14 +219,24 @@ public class PipeDataNodeTaskBuilder {
             PipeConnectorConstant.SINK_REALTIME_FIRST_KEY);
     if (isRealtime == null) {
       
connectorParameters.addAttribute(PipeConnectorConstant.CONNECTOR_REALTIME_FIRST_KEY,
 "false");
-      LOGGER.info(
-          "PipeDataNodeTaskBuilder: When 'inclusion' contains 'data.delete', 
'realtime-first' is defaulted to 'false' to prevent sync issues after 
deletion.");
+      if (insertionDeletionListeningOptionPair.right) {
+        LOGGER.info(
+            "PipeDataNodeTaskBuilder: When 'inclusion' contains 'data.delete', 
'realtime-first' is defaulted to 'false' to prevent sync issues after 
deletion.");
+      } else {
+        LOGGER.info(
+            "PipeDataNodeTaskBuilder: When extractor uses snapshot model, 
'realtime-first' is defaulted to 'false' to prevent premature halt before 
transfer completion.");
+      }
       return;
     }
 
     if (isRealtime) {
-      LOGGER.warn(
-          "PipeDataNodeTaskBuilder: When 'inclusion' includes 'data.delete', 
'realtime-first' set to 'true' may result in data synchronization issues after 
deletion.");
+      if (insertionDeletionListeningOptionPair.right) {
+        LOGGER.warn(
+            "PipeDataNodeTaskBuilder: When 'inclusion' includes 'data.delete', 
'realtime-first' set to 'true' may result in data synchronization issues after 
deletion.");
+      } else {
+        LOGGER.warn(
+            "PipeDataNodeTaskBuilder: When extractor uses snapshot model, 
'realtime-first' set to 'true' may cause prevent premature halt before transfer 
completion.");
+      }
     }
   }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/agent/task/subtask/connector/PipeConnectorSubtask.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/agent/task/subtask/connector/PipeConnectorSubtask.java
index 18673931a96..5e77505186c 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/agent/task/subtask/connector/PipeConnectorSubtask.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/agent/task/subtask/connector/PipeConnectorSubtask.java
@@ -44,6 +44,8 @@ import org.apache.iotdb.pipe.api.exception.PipeException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.Objects;
+
 public class PipeConnectorSubtask extends PipeAbstractConnectorSubtask {
 
   private static final Logger LOGGER = 
LoggerFactory.getLogger(PipeConnectorSubtask.class);
@@ -102,11 +104,12 @@ public class PipeConnectorSubtask extends 
PipeAbstractConnectorSubtask {
     }
 
     try {
-      if (event == null) {
-        if (System.currentTimeMillis() - lastHeartbeatEventInjectTime
-            > CRON_HEARTBEAT_EVENT_INJECT_INTERVAL_MILLISECONDS) {
-          transferHeartbeatEvent(CRON_HEARTBEAT_EVENT);
-        }
+      if (System.currentTimeMillis() - lastHeartbeatEventInjectTime
+          > CRON_HEARTBEAT_EVENT_INJECT_INTERVAL_MILLISECONDS) {
+        transferHeartbeatEvent(CRON_HEARTBEAT_EVENT);
+      }
+
+      if (Objects.isNull(event)) {
         return false;
       }
 
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/connector/payload/evolvable/batch/PipeTransferBatchReqBuilder.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/connector/payload/evolvable/batch/PipeTransferBatchReqBuilder.java
index 74ab3a1ebdc..7d8162b0df2 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/connector/payload/evolvable/batch/PipeTransferBatchReqBuilder.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/connector/payload/evolvable/batch/PipeTransferBatchReqBuilder.java
@@ -45,6 +45,7 @@ import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstan
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.CONNECTOR_FORMAT_KEY;
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.CONNECTOR_FORMAT_TS_FILE_VALUE;
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.CONNECTOR_IOTDB_BATCH_DELAY_KEY;
+import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.CONNECTOR_IOTDB_BATCH_DELAY_MS_KEY;
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.CONNECTOR_IOTDB_BATCH_SIZE_KEY;
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.CONNECTOR_IOTDB_PLAIN_BATCH_DELAY_DEFAULT_VALUE;
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.CONNECTOR_IOTDB_PLAIN_BATCH_SIZE_DEFAULT_VALUE;
@@ -54,6 +55,7 @@ import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstan
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.CONNECTOR_LEADER_CACHE_ENABLE_KEY;
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.SINK_FORMAT_KEY;
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.SINK_IOTDB_BATCH_DELAY_KEY;
+import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.SINK_IOTDB_BATCH_DELAY_MS_KEY;
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.SINK_IOTDB_BATCH_SIZE_KEY;
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.SINK_LEADER_CACHE_ENABLE_KEY;
 
@@ -87,34 +89,30 @@ public class PipeTransferBatchReqBuilder implements 
AutoCloseable {
                 Arrays.asList(SINK_LEADER_CACHE_ENABLE_KEY, 
CONNECTOR_LEADER_CACHE_ENABLE_KEY),
                 CONNECTOR_LEADER_CACHE_ENABLE_DEFAULT_VALUE);
 
-    final int requestMaxDelayInSeconds;
-    if (usingTsFileBatch) {
-      requestMaxDelayInSeconds =
+    final Integer requestMaxDelayInMillis =
+        parameters.getIntByKeys(CONNECTOR_IOTDB_BATCH_DELAY_MS_KEY, 
SINK_IOTDB_BATCH_DELAY_MS_KEY);
+    if (Objects.isNull(requestMaxDelayInMillis)) {
+      final int requestMaxDelayInSeconds =
           parameters.getIntOrDefault(
               Arrays.asList(CONNECTOR_IOTDB_BATCH_DELAY_KEY, 
SINK_IOTDB_BATCH_DELAY_KEY),
-              CONNECTOR_IOTDB_TS_FILE_BATCH_DELAY_DEFAULT_VALUE);
+              usingTsFileBatch
+                  ? CONNECTOR_IOTDB_TS_FILE_BATCH_DELAY_DEFAULT_VALUE
+                  : CONNECTOR_IOTDB_PLAIN_BATCH_DELAY_DEFAULT_VALUE);
       requestMaxDelayInMs =
           requestMaxDelayInSeconds < 0 ? Integer.MAX_VALUE : 
requestMaxDelayInSeconds * 1000;
-      requestMaxBatchSizeInBytes =
-          parameters.getLongOrDefault(
-              Arrays.asList(CONNECTOR_IOTDB_BATCH_SIZE_KEY, 
SINK_IOTDB_BATCH_SIZE_KEY),
-              CONNECTOR_IOTDB_TS_FILE_BATCH_SIZE_DEFAULT_VALUE);
-      this.defaultBatch =
-          new PipeTabletEventTsFileBatch(requestMaxDelayInMs, 
requestMaxBatchSizeInBytes);
     } else {
-      requestMaxDelayInSeconds =
-          parameters.getIntOrDefault(
-              Arrays.asList(CONNECTOR_IOTDB_BATCH_DELAY_KEY, 
SINK_IOTDB_BATCH_DELAY_KEY),
-              CONNECTOR_IOTDB_PLAIN_BATCH_DELAY_DEFAULT_VALUE);
       requestMaxDelayInMs =
-          requestMaxDelayInSeconds < 0 ? Integer.MAX_VALUE : 
requestMaxDelayInSeconds * 1000;
-      requestMaxBatchSizeInBytes =
-          parameters.getLongOrDefault(
-              Arrays.asList(CONNECTOR_IOTDB_BATCH_SIZE_KEY, 
SINK_IOTDB_BATCH_SIZE_KEY),
-              CONNECTOR_IOTDB_PLAIN_BATCH_SIZE_DEFAULT_VALUE);
-      this.defaultBatch =
-          new PipeTabletEventPlainBatch(requestMaxDelayInMs, 
requestMaxBatchSizeInBytes);
+          requestMaxDelayInMillis < 0 ? Integer.MAX_VALUE : 
requestMaxDelayInMillis;
     }
+
+    requestMaxBatchSizeInBytes =
+        parameters.getLongOrDefault(
+            Arrays.asList(CONNECTOR_IOTDB_BATCH_SIZE_KEY, 
SINK_IOTDB_BATCH_SIZE_KEY),
+            usingTsFileBatch
+                ? CONNECTOR_IOTDB_TS_FILE_BATCH_SIZE_DEFAULT_VALUE
+                : CONNECTOR_IOTDB_PLAIN_BATCH_SIZE_DEFAULT_VALUE);
+    this.defaultBatch =
+        new PipeTabletEventTsFileBatch(requestMaxDelayInMs, 
requestMaxBatchSizeInBytes);
   }
 
   /**
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/connector/protocol/pipeconsensus/payload/builder/PipeConsensusTransferBatchReqBuilder.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/connector/protocol/pipeconsensus/payload/builder/PipeConsensusTransferBatchReqBuilder.java
index f39613cf2c0..5d887526fa4 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/connector/protocol/pipeconsensus/payload/builder/PipeConsensusTransferBatchReqBuilder.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/connector/protocol/pipeconsensus/payload/builder/PipeConsensusTransferBatchReqBuilder.java
@@ -47,10 +47,12 @@ import java.util.List;
 import java.util.Objects;
 
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.CONNECTOR_IOTDB_BATCH_DELAY_KEY;
+import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.CONNECTOR_IOTDB_BATCH_DELAY_MS_KEY;
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.CONNECTOR_IOTDB_BATCH_SIZE_KEY;
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.CONNECTOR_IOTDB_PLAIN_BATCH_DELAY_DEFAULT_VALUE;
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.CONNECTOR_IOTDB_PLAIN_BATCH_SIZE_DEFAULT_VALUE;
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.SINK_IOTDB_BATCH_DELAY_KEY;
+import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.SINK_IOTDB_BATCH_DELAY_MS_KEY;
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.SINK_IOTDB_BATCH_SIZE_KEY;
 
 public abstract class PipeConsensusTransferBatchReqBuilder implements 
AutoCloseable {
@@ -73,11 +75,18 @@ public abstract class PipeConsensusTransferBatchReqBuilder 
implements AutoClosea
 
   protected PipeConsensusTransferBatchReqBuilder(
       PipeParameters parameters, TConsensusGroupId consensusGroupId, int 
thisDataNodeId) {
-    maxDelayInMs =
-        parameters.getIntOrDefault(
-                Arrays.asList(CONNECTOR_IOTDB_BATCH_DELAY_KEY, 
SINK_IOTDB_BATCH_DELAY_KEY),
-                CONNECTOR_IOTDB_PLAIN_BATCH_DELAY_DEFAULT_VALUE)
-            * 1000;
+    final Integer requestMaxDelayInMillis =
+        parameters.getIntByKeys(CONNECTOR_IOTDB_BATCH_DELAY_MS_KEY, 
SINK_IOTDB_BATCH_DELAY_MS_KEY);
+    if (Objects.isNull(requestMaxDelayInMillis)) {
+      final int requestMaxDelayInSeconds =
+          parameters.getIntOrDefault(
+              Arrays.asList(CONNECTOR_IOTDB_BATCH_DELAY_KEY, 
SINK_IOTDB_BATCH_DELAY_KEY),
+              CONNECTOR_IOTDB_PLAIN_BATCH_DELAY_DEFAULT_VALUE);
+      maxDelayInMs =
+          requestMaxDelayInSeconds < 0 ? Integer.MAX_VALUE : 
requestMaxDelayInSeconds * 1000;
+    } else {
+      maxDelayInMs = requestMaxDelayInMillis < 0 ? Integer.MAX_VALUE : 
requestMaxDelayInMillis;
+    }
 
     this.consensusGroupId = consensusGroupId;
     this.thisDataNodeId = thisDataNodeId;
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tablet/PipeRawTabletInsertionEvent.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tablet/PipeRawTabletInsertionEvent.java
index 10b664cf4b5..82e36f53735 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tablet/PipeRawTabletInsertionEvent.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tablet/PipeRawTabletInsertionEvent.java
@@ -312,6 +312,11 @@ public class PipeRawTabletInsertionEvent extends 
PipeInsertionEvent
     this.needToReport = true;
   }
 
+  // This getter is reserved for user-defined plugins
+  public boolean isNeedToReport() {
+    return needToReport;
+  }
+
   public String getDeviceId() {
     // NonNull indicates that the internallyDecreaseResourceReferenceCount has 
not been called.
     return Objects.nonNull(tablet) ? tablet.getDeviceId() : deviceId;
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/terminate/PipeTerminateEvent.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/terminate/PipeTerminateEvent.java
index 7cfd9f139a2..c67102030bb 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/terminate/PipeTerminateEvent.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/terminate/PipeTerminateEvent.java
@@ -29,6 +29,8 @@ import org.apache.iotdb.db.pipe.agent.PipeDataNodeAgent;
 import org.apache.iotdb.db.pipe.agent.task.PipeDataNodeTask;
 import org.apache.iotdb.db.pipe.event.common.tsfile.PipeTsFileInsertionEvent;
 
+import java.util.concurrent.CompletableFuture;
+
 /**
  * The {@link PipeTerminateEvent} is an {@link EnrichedEvent} that controls 
the termination of pipe,
  * that is, when the historical {@link PipeTsFileInsertionEvent}s are all 
processed, this will be
@@ -104,7 +106,9 @@ public class PipeTerminateEvent extends EnrichedEvent {
 
   @Override
   public void reportProgress() {
-    PipeDataNodeAgent.task().markCompleted(pipeName, dataRegionId);
+    // To avoid deadlock
+    CompletableFuture.runAsync(
+        () -> PipeDataNodeAgent.task().markCompleted(pipeName, dataRegionId));
   }
 
   @Override
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/extractor/dataregion/historical/PipeHistoricalDataRegionTsFileAndDeletionExtractor.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/extractor/dataregion/historical/PipeHistoricalDataRegionTsFileAndDeletionExtractor.java
index 381db6a25cf..181c2e440f3 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/extractor/dataregion/historical/PipeHistoricalDataRegionTsFileAndDeletionExtractor.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/extractor/dataregion/historical/PipeHistoricalDataRegionTsFileAndDeletionExtractor.java
@@ -87,12 +87,6 @@ import static 
org.apache.iotdb.commons.pipe.config.constant.PipeExtractorConstan
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeExtractorConstant.EXTRACTOR_HISTORY_LOOSE_RANGE_PATH_VALUE;
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeExtractorConstant.EXTRACTOR_HISTORY_LOOSE_RANGE_TIME_VALUE;
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeExtractorConstant.EXTRACTOR_HISTORY_START_TIME_KEY;
-import static 
org.apache.iotdb.commons.pipe.config.constant.PipeExtractorConstant.EXTRACTOR_MODE_DEFAULT_VALUE;
-import static 
org.apache.iotdb.commons.pipe.config.constant.PipeExtractorConstant.EXTRACTOR_MODE_KEY;
-import static 
org.apache.iotdb.commons.pipe.config.constant.PipeExtractorConstant.EXTRACTOR_MODE_QUERY_VALUE;
-import static 
org.apache.iotdb.commons.pipe.config.constant.PipeExtractorConstant.EXTRACTOR_MODE_SNAPSHOT_DEFAULT_VALUE;
-import static 
org.apache.iotdb.commons.pipe.config.constant.PipeExtractorConstant.EXTRACTOR_MODE_SNAPSHOT_KEY;
-import static 
org.apache.iotdb.commons.pipe.config.constant.PipeExtractorConstant.EXTRACTOR_MODE_SNAPSHOT_VALUE;
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeExtractorConstant.EXTRACTOR_MODE_STRICT_DEFAULT_VALUE;
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeExtractorConstant.EXTRACTOR_MODE_STRICT_KEY;
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeExtractorConstant.EXTRACTOR_MODS_DEFAULT_VALUE;
@@ -105,8 +99,6 @@ import static 
org.apache.iotdb.commons.pipe.config.constant.PipeExtractorConstan
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeExtractorConstant.SOURCE_HISTORY_END_TIME_KEY;
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeExtractorConstant.SOURCE_HISTORY_LOOSE_RANGE_KEY;
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeExtractorConstant.SOURCE_HISTORY_START_TIME_KEY;
-import static 
org.apache.iotdb.commons.pipe.config.constant.PipeExtractorConstant.SOURCE_MODE_KEY;
-import static 
org.apache.iotdb.commons.pipe.config.constant.PipeExtractorConstant.SOURCE_MODE_SNAPSHOT_KEY;
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeExtractorConstant.SOURCE_MODE_STRICT_KEY;
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeExtractorConstant.SOURCE_MODS_ENABLE_KEY;
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeExtractorConstant.SOURCE_MODS_KEY;
@@ -155,7 +147,6 @@ public class 
PipeHistoricalDataRegionTsFileAndDeletionExtractor
   private boolean shouldTransferModFile; // Whether to transfer mods
   protected String userName;
   protected boolean skipIfNoPrivileges = true;
-  private boolean shouldTerminatePipeOnAllHistoricalEventsConsumed;
   private boolean isTerminateSignalSent = false;
 
   private volatile boolean hasBeenStarted = false;
@@ -394,20 +385,6 @@ public class 
PipeHistoricalDataRegionTsFileAndDeletionExtractor
                   listeningOptionPair.getRight());
     }
 
-    if (parameters.hasAnyAttributes(EXTRACTOR_MODE_SNAPSHOT_KEY, 
SOURCE_MODE_SNAPSHOT_KEY)) {
-      shouldTerminatePipeOnAllHistoricalEventsConsumed =
-          parameters.getBooleanOrDefault(
-              Arrays.asList(EXTRACTOR_MODE_SNAPSHOT_KEY, 
SOURCE_MODE_SNAPSHOT_KEY),
-              EXTRACTOR_MODE_SNAPSHOT_DEFAULT_VALUE);
-    } else {
-      final String extractorModeValue =
-          parameters.getStringOrDefault(
-              Arrays.asList(EXTRACTOR_MODE_KEY, SOURCE_MODE_KEY), 
EXTRACTOR_MODE_DEFAULT_VALUE);
-      shouldTerminatePipeOnAllHistoricalEventsConsumed =
-          extractorModeValue.equalsIgnoreCase(EXTRACTOR_MODE_SNAPSHOT_VALUE)
-              || 
extractorModeValue.equalsIgnoreCase(EXTRACTOR_MODE_QUERY_VALUE);
-    }
-
     userName =
         parameters.getStringByKeys(
             PipeExtractorConstant.EXTRACTOR_IOTDB_USER_KEY,
@@ -419,7 +396,7 @@ public class 
PipeHistoricalDataRegionTsFileAndDeletionExtractor
 
     if (LOGGER.isInfoEnabled()) {
       LOGGER.info(
-          "Pipe {}@{}: historical data extraction time range, start time 
{}({}), end time {}({}), sloppy pattern {}, sloppy time range {}, should 
transfer mod file {}, should terminate pipe on all historical events consumed 
{}, username: {}, skip if no privileges: {}",
+          "Pipe {}@{}: historical data extraction time range, start time 
{}({}), end time {}({}), sloppy pattern {}, sloppy time range {}, should 
transfer mod file {}, username: {}, skip if no privileges: {}",
           pipeName,
           dataRegionId,
           DateTimeUtils.convertLongToDate(historicalDataExtractionStartTime),
@@ -429,7 +406,6 @@ public class 
PipeHistoricalDataRegionTsFileAndDeletionExtractor
           sloppyPattern,
           sloppyTimeRange,
           shouldTransferModFile,
-          shouldTerminatePipeOnAllHistoricalEventsConsumed,
           userName,
           skipIfNoPrivileges);
     }
@@ -903,9 +879,7 @@ public class 
PipeHistoricalDataRegionTsFileAndDeletionExtractor
     // If the pendingQueue is null when the function is called, it implies 
that the extractor only
     // extracts deletion thus the historical event has nothing to consume.
     return hasBeenStarted
-        && (Objects.isNull(pendingQueue)
-            || pendingQueue.isEmpty()
-                && (!shouldTerminatePipeOnAllHistoricalEventsConsumed || 
isTerminateSignalSent));
+        && (Objects.isNull(pendingQueue) || pendingQueue.isEmpty() && 
isTerminateSignalSent);
   }
 
   @Override
diff --git 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/agent/task/progress/PipeEventCommitter.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/agent/task/progress/PipeEventCommitter.java
index ba61f03f841..9479c7a752a 100644
--- 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/agent/task/progress/PipeEventCommitter.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/agent/task/progress/PipeEventCommitter.java
@@ -62,19 +62,21 @@ public class PipeEventCommitter {
 
     final int commitQueueSizeBeforeCommit = commitQueue.size();
     if (LOGGER.isDebugEnabled()) {
-      LOGGER.debug(
-          "COMMIT QUEUE OFFER: committer key {}, event commit id {}, last 
commit id {}, commit queue size {}",
-          committerKey,
-          event.getCommitId(),
-          lastCommitId.get(),
-          commitQueueSizeBeforeCommit);
-    } else if (commitQueueSizeBeforeCommit != 0 && commitQueueSizeBeforeCommit 
% 100 == 0) {
-      LOGGER.info(
-          "COMMIT QUEUE OFFER: committer key {}, event commit id {}, last 
commit id {}, commit queue size {}",
-          committerKey,
-          event.getCommitId(),
-          lastCommitId.get(),
-          commitQueueSizeBeforeCommit);
+      if (commitQueueSizeBeforeCommit != 0 && commitQueueSizeBeforeCommit % 
100 == 0) {
+        LOGGER.info(
+            "COMMIT QUEUE OFFER: committer key {}, event commit id {}, last 
commit id {}, commit queue size {}",
+            committerKey,
+            event.getCommitId(),
+            lastCommitId.get(),
+            commitQueueSizeBeforeCommit);
+      } else {
+        LOGGER.debug(
+            "COMMIT QUEUE OFFER: committer key {}, event commit id {}, last 
commit id {}, commit queue size {}",
+            committerKey,
+            event.getCommitId(),
+            lastCommitId.get(),
+            commitQueueSizeBeforeCommit);
+      }
     }
 
     while (!commitQueue.isEmpty()) {
diff --git 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/config/constant/PipeConnectorConstant.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/config/constant/PipeConnectorConstant.java
index 6bfc127e50b..8eabf50406a 100644
--- 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/config/constant/PipeConnectorConstant.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/config/constant/PipeConnectorConstant.java
@@ -68,6 +68,9 @@ public class PipeConnectorConstant {
   public static final int CONNECTOR_IOTDB_PLAIN_BATCH_DELAY_DEFAULT_VALUE = 1;
   public static final int CONNECTOR_IOTDB_TS_FILE_BATCH_DELAY_DEFAULT_VALUE = 
5;
 
+  public static final String CONNECTOR_IOTDB_BATCH_DELAY_MS_KEY = 
"connector.batch.max-delay-ms";
+  public static final String SINK_IOTDB_BATCH_DELAY_MS_KEY = 
"sink.batch.max-delay-ms";
+
   public static final String CONNECTOR_IOTDB_BATCH_SIZE_KEY = 
"connector.batch.size-bytes";
   public static final String SINK_IOTDB_BATCH_SIZE_KEY = 
"sink.batch.size-bytes";
   public static final long CONNECTOR_IOTDB_PLAIN_BATCH_SIZE_DEFAULT_VALUE = 16 
* MB;
diff --git 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/connector/protocol/IoTDBConnector.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/connector/protocol/IoTDBConnector.java
index aed4afd4544..8461cb4dee5 100644
--- 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/connector/protocol/IoTDBConnector.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/connector/protocol/IoTDBConnector.java
@@ -74,6 +74,8 @@ import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstan
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.CONNECTOR_FORMAT_KEY;
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.CONNECTOR_FORMAT_TABLET_VALUE;
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.CONNECTOR_FORMAT_TS_FILE_VALUE;
+import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.CONNECTOR_IOTDB_BATCH_DELAY_KEY;
+import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.CONNECTOR_IOTDB_BATCH_DELAY_MS_KEY;
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.CONNECTOR_IOTDB_BATCH_MODE_ENABLE_DEFAULT_VALUE;
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.CONNECTOR_IOTDB_BATCH_MODE_ENABLE_KEY;
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.CONNECTOR_IOTDB_BATCH_SIZE_KEY;
@@ -108,6 +110,8 @@ import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstan
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.SINK_EXCEPTION_OTHERS_RECORD_IGNORED_DATA_KEY;
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.SINK_EXCEPTION_OTHERS_RETRY_MAX_TIME_SECONDS_KEY;
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.SINK_FORMAT_KEY;
+import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.SINK_IOTDB_BATCH_DELAY_KEY;
+import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.SINK_IOTDB_BATCH_DELAY_MS_KEY;
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.SINK_IOTDB_BATCH_MODE_ENABLE_KEY;
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.SINK_IOTDB_BATCH_SIZE_KEY;
 import static 
org.apache.iotdb.commons.pipe.config.constant.PipeConnectorConstant.SINK_IOTDB_HOST_KEY;
@@ -205,6 +209,12 @@ public abstract class IoTDBConnector implements 
PipeConnector {
         Arrays.asList(CONNECTOR_IOTDB_USERNAME_KEY, SINK_IOTDB_USERNAME_KEY),
         false);
 
+    // Check coexistence of batch.max-delay-ms and batch.max-delay-seconds
+    validator.validateSynonymAttributes(
+        Arrays.asList(CONNECTOR_IOTDB_BATCH_DELAY_MS_KEY, 
SINK_IOTDB_BATCH_DELAY_MS_KEY),
+        Arrays.asList(CONNECTOR_IOTDB_BATCH_DELAY_KEY, 
SINK_IOTDB_BATCH_DELAY_KEY),
+        false);
+
     username =
         parameters.getStringOrDefault(
             Arrays.asList(

Reply via email to