This is an automated email from the ASF dual-hosted git repository.
szetszwo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ratis.git
The following commit(s) were added to refs/heads/master by this push:
new a2bdd10fc RATIS-2094. Avoid corruptions from TransactionContext's
stateMachineLogEntry and stateMachineContext. (#1106)
a2bdd10fc is described below
commit a2bdd10fccb346d02f12d3961d6a5b2d281c5d56
Author: Duong Nguyen <[email protected]>
AuthorDate: Mon Jun 3 10:35:07 2024 -0700
RATIS-2094. Avoid corruptions from TransactionContext's
stateMachineLogEntry and stateMachineContext. (#1106)
---
.../java/org/apache/ratis/util/ReferenceCountedObject.java | 8 ++++++++
.../ratis/examples/filestore/FileStoreStateMachine.java | 11 ++++++-----
.../org/apache/ratis/statemachine/TransactionContext.java | 3 +++
.../java/org/apache/ratis/statemachine/TestStateMachine.java | 2 +-
4 files changed, 18 insertions(+), 6 deletions(-)
diff --git
a/ratis-common/src/main/java/org/apache/ratis/util/ReferenceCountedObject.java
b/ratis-common/src/main/java/org/apache/ratis/util/ReferenceCountedObject.java
index eb5ff30ae..b2c53182d 100644
---
a/ratis-common/src/main/java/org/apache/ratis/util/ReferenceCountedObject.java
+++
b/ratis-common/src/main/java/org/apache/ratis/util/ReferenceCountedObject.java
@@ -23,6 +23,7 @@ import java.util.Collection;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
+import java.util.function.Function;
/**
* A reference-counted object can be retained for later use
@@ -152,6 +153,13 @@ public interface ReferenceCountedObject<T> {
};
}
+ /**
+ * @return a {@link ReferenceCountedObject} by apply the given function to
this object.
+ */
+ default <V> ReferenceCountedObject<V> apply(Function<T, V> function) {
+ return delegate(function.apply(get()));
+ }
+
/**
* Wrap the given value as a {@link ReferenceCountedObject}.
*
diff --git
a/ratis-examples/src/main/java/org/apache/ratis/examples/filestore/FileStoreStateMachine.java
b/ratis-examples/src/main/java/org/apache/ratis/examples/filestore/FileStoreStateMachine.java
index f870cbacf..2fb9cace6 100644
---
a/ratis-examples/src/main/java/org/apache/ratis/examples/filestore/FileStoreStateMachine.java
+++
b/ratis-examples/src/main/java/org/apache/ratis/examples/filestore/FileStoreStateMachine.java
@@ -115,11 +115,12 @@ public class FileStoreStateMachine extends
BaseStateMachine {
@Override
public TransactionContext startTransaction(LogEntryProto entry,
RaftProtos.RaftPeerRole role) {
+ ByteString copied =
ByteString.copyFrom(entry.getStateMachineLogEntry().getLogData().asReadOnlyByteBuffer());
return TransactionContext.newBuilder()
.setStateMachine(this)
.setLogEntry(entry)
.setServerRole(role)
- .setStateMachineContext(getProto(entry))
+ .setStateMachineContext(getProto(copied))
.build();
}
@@ -147,14 +148,14 @@ public class FileStoreStateMachine extends
BaseStateMachine {
return proto;
}
}
- return getProto(entry);
+ return getProto(entry.getStateMachineLogEntry().getLogData());
}
- static FileStoreRequestProto getProto(LogEntryProto entry) {
+ static FileStoreRequestProto getProto(ByteString bytes) {
try {
- return
FileStoreRequestProto.parseFrom(entry.getStateMachineLogEntry().getLogData());
+ return FileStoreRequestProto.parseFrom(bytes);
} catch (InvalidProtocolBufferException e) {
- throw new IllegalArgumentException("Failed to parse data, entry=" +
entry, e);
+ throw new IllegalArgumentException("Failed to parse data", e);
}
}
diff --git
a/ratis-server-api/src/main/java/org/apache/ratis/statemachine/TransactionContext.java
b/ratis-server-api/src/main/java/org/apache/ratis/statemachine/TransactionContext.java
index 2ec87e37a..6f08c4a55 100644
---
a/ratis-server-api/src/main/java/org/apache/ratis/statemachine/TransactionContext.java
+++
b/ratis-server-api/src/main/java/org/apache/ratis/statemachine/TransactionContext.java
@@ -60,7 +60,10 @@ public interface TransactionContext {
/**
* Returns the data from the {@link StateMachine}
* @return the data from the {@link StateMachine}
+ * @deprecated access StateMachineLogEntry via {@link
TransactionContext#getLogEntryRef()} or
+ * {@link TransactionContext#getLogEntryUnsafe()}
*/
+ @Deprecated
StateMachineLogEntryProto getStateMachineLogEntry();
/** Set exception in case of failure. */
diff --git
a/ratis-test/src/test/java/org/apache/ratis/statemachine/TestStateMachine.java
b/ratis-test/src/test/java/org/apache/ratis/statemachine/TestStateMachine.java
index 07ea4edbc..0c49b31af 100644
---
a/ratis-test/src/test/java/org/apache/ratis/statemachine/TestStateMachine.java
+++
b/ratis-test/src/test/java/org/apache/ratis/statemachine/TestStateMachine.java
@@ -92,7 +92,7 @@ public class TestStateMachine extends BaseTest implements
MiniRaftClusterWithSim
public CompletableFuture<Message> applyTransaction(TransactionContext trx)
{
try {
assertNotNull(trx.getLogEntryUnsafe());
- assertNotNull(trx.getStateMachineLogEntry());
+ assertNotNull(trx.getLogEntryUnsafe().getStateMachineLogEntry());
Object context = trx.getStateMachineContext();
if (isLeader.get()) {
assertNotNull(trx.getClientRequest());