This is an automated email from the ASF dual-hosted git repository.
apolovtsev 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 a30f9d68c52 IGNITE-28187 Non-transactional replica requests should be
retried in the same manner as transactional (#7749)
a30f9d68c52 is described below
commit a30f9d68c5212cd404ebf4cc8691bac81e1eb07b
Author: Denis Chudov <[email protected]>
AuthorDate: Wed Mar 11 14:12:55 2026 +0200
IGNITE-28187 Non-transactional replica requests should be retried in the
same manner as transactional (#7749)
---
.../apache/ignite/tx/RetriableReplicaRequestException.java} | 13 +++++++++----
.../ignite/internal/lang/ComponentStoppingException.java | 4 +++-
.../apache/ignite/internal/lang/NodeStoppingException.java | 4 +++-
.../apache/ignite/internal/util/TrackerClosedException.java | 4 +++-
.../internal/network/UnresolvableConsistentIdException.java | 4 +++-
.../placementdriver/PrimaryReplicaAwaitException.java | 4 +++-
.../PrimaryReplicaAwaitTimeoutException.java | 4 +++-
.../replicator/exception/PrimaryReplicaMissException.java | 3 ++-
.../internal/replicator/exception/ReplicationException.java | 4 +++-
.../table/distributed/storage/InternalTableImpl.java | 13 +++----------
.../internal/tx/impl/PrimaryReplicaExpiredException.java | 4 +++-
11 files changed, 38 insertions(+), 23 deletions(-)
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/util/TrackerClosedException.java
b/modules/api/src/main/java/org/apache/ignite/tx/RetriableReplicaRequestException.java
similarity index 68%
copy from
modules/core/src/main/java/org/apache/ignite/internal/util/TrackerClosedException.java
copy to
modules/api/src/main/java/org/apache/ignite/tx/RetriableReplicaRequestException.java
index 2ab0b0e2d09..d41ff4084ff 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/util/TrackerClosedException.java
+++
b/modules/api/src/main/java/org/apache/ignite/tx/RetriableReplicaRequestException.java
@@ -15,11 +15,16 @@
* limitations under the License.
*/
-package org.apache.ignite.internal.util;
+package org.apache.ignite.tx;
/**
- * Exception that will be thrown when the {@link
PendingComparableValuesTracker} is closed.
+ * This is the marker interface for exceptions that may be thrown during
replica requests and may be retried, such as:
+ * <ul>
+ * <li>primary replica miss and primary replica expired exception;</li>
+ * <li>replication problems;</li>
+ * <li>replica unavailability;</li>
+ * </ul>
+ * etc.
*/
-public class TrackerClosedException extends RuntimeException {
- private static final long serialVersionUID = -3685913884384983930L;
+public interface RetriableReplicaRequestException {
}
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/lang/ComponentStoppingException.java
b/modules/core/src/main/java/org/apache/ignite/internal/lang/ComponentStoppingException.java
index 06354bfe440..710bcef5e51 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/lang/ComponentStoppingException.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/lang/ComponentStoppingException.java
@@ -20,6 +20,7 @@ package org.apache.ignite.internal.lang;
import static org.apache.ignite.lang.ErrorGroups.Common.INTERNAL_ERR;
import java.util.UUID;
+import org.apache.ignite.tx.RetriableReplicaRequestException;
import org.apache.ignite.tx.RetriableTransactionException;
import org.jetbrains.annotations.Nullable;
@@ -28,7 +29,8 @@ import org.jetbrains.annotations.Nullable;
* This is different from {@link NodeStoppingException} as {@link
ComponentStoppingException} might mean that just the component is stopped,
* not the whole node.
*/
-public class ComponentStoppingException extends IgniteInternalCheckedException
implements RetriableTransactionException {
+public class ComponentStoppingException extends IgniteInternalCheckedException
implements RetriableTransactionException,
+ RetriableReplicaRequestException {
/** Serial version UID. */
private static final long serialVersionUID = 0L;
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/lang/NodeStoppingException.java
b/modules/core/src/main/java/org/apache/ignite/internal/lang/NodeStoppingException.java
index 35fd72fc99f..55a5ac34edd 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/lang/NodeStoppingException.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/lang/NodeStoppingException.java
@@ -20,13 +20,15 @@ package org.apache.ignite.internal.lang;
import static org.apache.ignite.lang.ErrorGroups.Common.NODE_STOPPING_ERR;
import java.util.UUID;
+import org.apache.ignite.tx.RetriableReplicaRequestException;
import org.apache.ignite.tx.RetriableTransactionException;
import org.jetbrains.annotations.Nullable;
/**
* This exception is used to indicate that Ignite node is stopping (already
stopped) for some reason.
*/
-public class NodeStoppingException extends IgniteInternalCheckedException
implements RetriableTransactionException {
+public class NodeStoppingException extends IgniteInternalCheckedException
implements RetriableTransactionException,
+ RetriableReplicaRequestException {
/** Serial version UID. */
private static final long serialVersionUID = 0L;
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/util/TrackerClosedException.java
b/modules/core/src/main/java/org/apache/ignite/internal/util/TrackerClosedException.java
index 2ab0b0e2d09..92a3e693874 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/util/TrackerClosedException.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/util/TrackerClosedException.java
@@ -17,9 +17,11 @@
package org.apache.ignite.internal.util;
+import org.apache.ignite.tx.RetriableReplicaRequestException;
+
/**
* Exception that will be thrown when the {@link
PendingComparableValuesTracker} is closed.
*/
-public class TrackerClosedException extends RuntimeException {
+public class TrackerClosedException extends RuntimeException implements
RetriableReplicaRequestException {
private static final long serialVersionUID = -3685913884384983930L;
}
diff --git
a/modules/network-api/src/main/java/org/apache/ignite/internal/network/UnresolvableConsistentIdException.java
b/modules/network-api/src/main/java/org/apache/ignite/internal/network/UnresolvableConsistentIdException.java
index fd53468f9bb..216466c66ba 100644
---
a/modules/network-api/src/main/java/org/apache/ignite/internal/network/UnresolvableConsistentIdException.java
+++
b/modules/network-api/src/main/java/org/apache/ignite/internal/network/UnresolvableConsistentIdException.java
@@ -19,13 +19,15 @@ package org.apache.ignite.internal.network;
import org.apache.ignite.lang.ErrorGroups.Network;
import org.apache.ignite.lang.IgniteException;
+import org.apache.ignite.tx.RetriableReplicaRequestException;
import org.apache.ignite.tx.RetriableTransactionException;
/**
* Thrown when consistent ID cannot be resolved to a {@link
InternalClusterNode} instance (i.e. when
* there is no node with such consistent ID in the physical topology).
*/
-public class UnresolvableConsistentIdException extends IgniteException
implements RetriableTransactionException {
+public class UnresolvableConsistentIdException extends IgniteException
implements RetriableTransactionException,
+ RetriableReplicaRequestException {
public UnresolvableConsistentIdException(String msg) {
super(Network.UNRESOLVABLE_CONSISTENT_ID_ERR, msg);
}
diff --git
a/modules/placement-driver-api/src/main/java/org/apache/ignite/internal/placementdriver/PrimaryReplicaAwaitException.java
b/modules/placement-driver-api/src/main/java/org/apache/ignite/internal/placementdriver/PrimaryReplicaAwaitException.java
index 39ae5402dda..74d2a78b67d 100644
---
a/modules/placement-driver-api/src/main/java/org/apache/ignite/internal/placementdriver/PrimaryReplicaAwaitException.java
+++
b/modules/placement-driver-api/src/main/java/org/apache/ignite/internal/placementdriver/PrimaryReplicaAwaitException.java
@@ -22,13 +22,15 @@ import static
org.apache.ignite.lang.ErrorGroups.PlacementDriver.PRIMARY_REPLICA
import org.apache.ignite.internal.hlc.HybridTimestamp;
import org.apache.ignite.internal.lang.IgniteInternalException;
import org.apache.ignite.internal.replicator.ReplicationGroupId;
+import org.apache.ignite.tx.RetriableReplicaRequestException;
import org.apache.ignite.tx.RetriableTransactionException;
/**
* The exception is thrown when a primary replica await process has failed.
Please pay attention that there is a specific
* {@link PrimaryReplicaAwaitTimeoutException} for the primary replica await
timeout.
*/
-public class PrimaryReplicaAwaitException extends IgniteInternalException
implements RetriableTransactionException {
+public class PrimaryReplicaAwaitException extends IgniteInternalException
implements RetriableTransactionException,
+ RetriableReplicaRequestException {
private static final long serialVersionUID = 1029917546884926160L;
/**
diff --git
a/modules/placement-driver-api/src/main/java/org/apache/ignite/internal/placementdriver/PrimaryReplicaAwaitTimeoutException.java
b/modules/placement-driver-api/src/main/java/org/apache/ignite/internal/placementdriver/PrimaryReplicaAwaitTimeoutException.java
index 633a2d93cdc..e584057528e 100644
---
a/modules/placement-driver-api/src/main/java/org/apache/ignite/internal/placementdriver/PrimaryReplicaAwaitTimeoutException.java
+++
b/modules/placement-driver-api/src/main/java/org/apache/ignite/internal/placementdriver/PrimaryReplicaAwaitTimeoutException.java
@@ -22,13 +22,15 @@ import static
org.apache.ignite.lang.ErrorGroups.PlacementDriver.PRIMARY_REPLICA
import org.apache.ignite.internal.hlc.HybridTimestamp;
import org.apache.ignite.internal.lang.IgniteInternalException;
import org.apache.ignite.internal.replicator.ReplicationGroupId;
+import org.apache.ignite.tx.RetriableReplicaRequestException;
import org.apache.ignite.tx.RetriableTransactionException;
import org.jetbrains.annotations.Nullable;
/**
* The exception is thrown when a primary replica await process has times out.
*/
-public class PrimaryReplicaAwaitTimeoutException extends
IgniteInternalException implements RetriableTransactionException {
+public class PrimaryReplicaAwaitTimeoutException extends
IgniteInternalException implements RetriableTransactionException,
+ RetriableReplicaRequestException {
private static final long serialVersionUID = -1450288033816499192L;
/**
diff --git
a/modules/replicator/src/main/java/org/apache/ignite/internal/replicator/exception/PrimaryReplicaMissException.java
b/modules/replicator/src/main/java/org/apache/ignite/internal/replicator/exception/PrimaryReplicaMissException.java
index 809eb26f9c5..184003b3511 100644
---
a/modules/replicator/src/main/java/org/apache/ignite/internal/replicator/exception/PrimaryReplicaMissException.java
+++
b/modules/replicator/src/main/java/org/apache/ignite/internal/replicator/exception/PrimaryReplicaMissException.java
@@ -23,6 +23,7 @@ import static
org.apache.ignite.lang.ErrorGroups.Replicator.REPLICA_MISS_ERR;
import java.util.UUID;
import org.apache.ignite.internal.lang.IgniteInternalException;
import org.apache.ignite.internal.replicator.ReplicationGroupId;
+import org.apache.ignite.tx.RetriableReplicaRequestException;
import org.apache.ignite.tx.RetriableTransactionException;
import org.jetbrains.annotations.Nullable;
@@ -30,7 +31,7 @@ import org.jetbrains.annotations.Nullable;
* Unchecked exception that is thrown when a replica is not the current
primary replica.
*/
public class PrimaryReplicaMissException extends IgniteInternalException
implements ExpectedReplicationException,
- RetriableTransactionException {
+ RetriableTransactionException, RetriableReplicaRequestException {
private static final long serialVersionUID = 8755220779942651494L;
/**
diff --git
a/modules/replicator/src/main/java/org/apache/ignite/internal/replicator/exception/ReplicationException.java
b/modules/replicator/src/main/java/org/apache/ignite/internal/replicator/exception/ReplicationException.java
index 57a18d868d3..ea8360231dc 100644
---
a/modules/replicator/src/main/java/org/apache/ignite/internal/replicator/exception/ReplicationException.java
+++
b/modules/replicator/src/main/java/org/apache/ignite/internal/replicator/exception/ReplicationException.java
@@ -22,12 +22,14 @@ import static
org.apache.ignite.lang.ErrorGroups.Replicator.REPLICA_COMMON_ERR;
import java.util.UUID;
import org.apache.ignite.internal.lang.IgniteInternalException;
import org.apache.ignite.internal.replicator.ReplicationGroupId;
+import org.apache.ignite.tx.RetriableReplicaRequestException;
import org.apache.ignite.tx.RetriableTransactionException;
/**
* The exception is thrown when some issue happened during a replication.
*/
-public class ReplicationException extends IgniteInternalException implements
RetriableTransactionException {
+public class ReplicationException extends IgniteInternalException implements
RetriableTransactionException,
+ RetriableReplicaRequestException {
/**
* Constructor.
*
diff --git
a/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/storage/InternalTableImpl.java
b/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/storage/InternalTableImpl.java
index 662ce943e43..42ffcaec2cc 100644
---
a/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/storage/InternalTableImpl.java
+++
b/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/storage/InternalTableImpl.java
@@ -91,7 +91,6 @@ import org.apache.ignite.internal.hlc.HybridTimestampTracker;
import org.apache.ignite.internal.lang.IgniteTriFunction;
import org.apache.ignite.internal.network.ClusterNodeResolver;
import org.apache.ignite.internal.network.InternalClusterNode;
-import org.apache.ignite.internal.network.UnresolvableConsistentIdException;
import
org.apache.ignite.internal.partition.replicator.network.PartitionReplicationMessagesFactory;
import
org.apache.ignite.internal.partition.replicator.network.replication.BinaryTupleMessage;
import
org.apache.ignite.internal.partition.replicator.network.replication.ReadOnlyMultiRowPkReplicaRequest;
@@ -106,9 +105,7 @@ import
org.apache.ignite.internal.placementdriver.PlacementDriver;
import org.apache.ignite.internal.placementdriver.ReplicaMeta;
import org.apache.ignite.internal.replicator.ReplicaService;
import org.apache.ignite.internal.replicator.ZonePartitionId;
-import
org.apache.ignite.internal.replicator.exception.PrimaryReplicaMissException;
import org.apache.ignite.internal.replicator.exception.ReplicationException;
-import
org.apache.ignite.internal.replicator.exception.ReplicationTimeoutException;
import org.apache.ignite.internal.replicator.message.ReplicaMessagesFactory;
import org.apache.ignite.internal.replicator.message.ReplicaRequest;
import org.apache.ignite.internal.replicator.message.ReplicationGroupIdMessage;
@@ -137,6 +134,7 @@ import org.apache.ignite.internal.util.IgniteUtils;
import org.apache.ignite.lang.IgniteException;
import org.apache.ignite.table.QualifiedName;
import org.apache.ignite.table.QualifiedNameHelper;
+import org.apache.ignite.tx.RetriableReplicaRequestException;
import org.apache.ignite.tx.TransactionException;
import org.jetbrains.annotations.Nullable;
@@ -2263,13 +2261,8 @@ public class InternalTableImpl implements InternalTable {
e = e.getCause();
}
- // We do a retry for the following conditions:
- // 1. Primary Replica has changed between the
"awaitPrimaryReplica" and "invoke" calls;
- // 2. Primary Replica has died and is no
longer available.
- // In both cases, we need to wait for the
lease to expire and to get a new Primary Replica.
- if (e instanceof PrimaryReplicaMissException
- || e instanceof
UnresolvableConsistentIdException
- || e instanceof
ReplicationTimeoutException) {
+ // We can do a retry for the any condition
listed in javadoc for RetriableReplicaRequestException.
+ if (e instanceof
RetriableReplicaRequestException) {
if (numRetries == 0) {
throw new
IgniteException(REPLICA_MISS_ERR, e);
}
diff --git
a/modules/transactions/src/main/java/org/apache/ignite/internal/tx/impl/PrimaryReplicaExpiredException.java
b/modules/transactions/src/main/java/org/apache/ignite/internal/tx/impl/PrimaryReplicaExpiredException.java
index fc951e706ba..e5232d6a9b1 100644
---
a/modules/transactions/src/main/java/org/apache/ignite/internal/tx/impl/PrimaryReplicaExpiredException.java
+++
b/modules/transactions/src/main/java/org/apache/ignite/internal/tx/impl/PrimaryReplicaExpiredException.java
@@ -23,11 +23,13 @@ import org.apache.ignite.internal.hlc.HybridTimestamp;
import org.apache.ignite.internal.lang.IgniteInternalException;
import org.apache.ignite.internal.placementdriver.ReplicaMeta;
import org.apache.ignite.internal.replicator.ZonePartitionId;
+import org.apache.ignite.tx.RetriableReplicaRequestException;
import org.apache.ignite.tx.RetriableTransactionException;
import org.jetbrains.annotations.Nullable;
/** Unchecked exception that is thrown when primary replica has expired. */
-public class PrimaryReplicaExpiredException extends IgniteInternalException
implements RetriableTransactionException {
+public class PrimaryReplicaExpiredException extends IgniteInternalException
implements RetriableTransactionException,
+ RetriableReplicaRequestException {
/**
* The constructor.
*