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

vpyatkov 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 12166027fb IGNITE-23132 fix NullPointerException in LogManagerImpl 
(#4395)
12166027fb is described below

commit 12166027fbdd5d3ae0506def0607f27d7d07fa2e
Author: Mirza Aliev <[email protected]>
AuthorDate: Wed Sep 25 22:37:34 2024 +0400

    IGNITE-23132 fix NullPointerException in LogManagerImpl (#4395)
---
 .../apache/ignite/raft/jraft/core/NodeImpl.java    | 19 ++++++++++---------
 .../raft/jraft/storage/impl/LogManagerImpl.java    | 22 +++++++++++++++-------
 .../raft/jraft/storage/impl/LogManagerTest.java    | 20 ++++++++++++++++++++
 3 files changed, 45 insertions(+), 16 deletions(-)

diff --git 
a/modules/raft/src/main/java/org/apache/ignite/raft/jraft/core/NodeImpl.java 
b/modules/raft/src/main/java/org/apache/ignite/raft/jraft/core/NodeImpl.java
index 618a481aac..deb2b51a52 100644
--- a/modules/raft/src/main/java/org/apache/ignite/raft/jraft/core/NodeImpl.java
+++ b/modules/raft/src/main/java/org/apache/ignite/raft/jraft/core/NodeImpl.java
@@ -1588,15 +1588,16 @@ public class NodeImpl implements Node, 
RaftServerService {
 
     private void executeApplyingTasks(final List<LogEntryAndClosure> tasks) {
         if (!this.logManager.hasAvailableCapacityToAppendEntries(1)) {
-               // It's overload, fail-fast
-               final List<Closure> dones = tasks.stream().map(ele -> 
ele.done).filter(Objects::nonNull)
-                               .collect(Collectors.toList());
-               Utils.runInThread(this.getOptions().getCommonExecutor(), () -> {
-                       for (final Closure done : dones) {
-                               done.run(new Status(RaftError.EBUSY, "Node %s 
log manager is busy.", this.getNodeId()));
-                       }
-               });
-               return;
+            // It's overload, fail-fast
+            final List<Closure> dones = tasks.stream().map(ele -> 
ele.done).filter(Objects::nonNull)
+                     .collect(Collectors.toList());
+            Utils.runInThread(this.getOptions().getCommonExecutor(), () -> {
+                for (final Closure done : dones) {
+                    done.run(new Status(RaftError.EBUSY, "Node %s log manager 
is busy.", this.getNodeId()));
+                }
+            });
+
+            return;
         }
 
         this.writeLock.lock();
diff --git 
a/modules/raft/src/main/java/org/apache/ignite/raft/jraft/storage/impl/LogManagerImpl.java
 
b/modules/raft/src/main/java/org/apache/ignite/raft/jraft/storage/impl/LogManagerImpl.java
index 31228fe671..9c646954c8 100644
--- 
a/modules/raft/src/main/java/org/apache/ignite/raft/jraft/storage/impl/LogManagerImpl.java
+++ 
b/modules/raft/src/main/java/org/apache/ignite/raft/jraft/storage/impl/LogManagerImpl.java
@@ -353,13 +353,8 @@ public class LogManagerImpl implements LogManager {
     private void offerEvent(final StableClosure done, final EventType type) {
         assert(done != null);
 
-            if (this.stopped) {
-                if (type == EventType.LAST_LOG_ID) {
-                    // TODO: remove after fixing the issue 
https://issues.apache.org/jira/browse/IGNITE-23132
-                    LOG.info("Received a last log id request, but log manager 
is stopped.");
-                }
-
-                Utils.runClosureInThread(nodeOptions.getCommonExecutor(), 
done, new Status(RaftError.ESTOP, "Log manager is stopped."));
+        if (this.stopped) {
+            Utils.runClosureInThread(nodeOptions.getCommonExecutor(), done, 
new Status(RaftError.ESTOP, "Log manager is stopped."));
             return;
         }
         this.diskQueue.publishEvent((event, sequence) -> {
@@ -896,6 +891,13 @@ public class LogManagerImpl implements LogManager {
             Thread.currentThread().interrupt();
             throw new IllegalStateException(e);
         }
+
+        if (c.lastLogId == null) {
+            assert stopped : "Last log id can be null only when node is 
stopping.";
+
+            throw new IllegalStateException("Node is shutting down");
+        }
+
         return c.lastLogId.getIndex();
     }
 
@@ -947,6 +949,12 @@ public class LogManagerImpl implements LogManager {
             Thread.currentThread().interrupt();
             throw new IllegalStateException(e);
         }
+        if (c.lastLogId == null) {
+            assert stopped : "Last log id can be null only when node is 
stopping.";
+
+            throw new IllegalStateException("Node is shutting down");
+        }
+
         return c.lastLogId;
     }
 
diff --git 
a/modules/raft/src/test/java/org/apache/ignite/raft/jraft/storage/impl/LogManagerTest.java
 
b/modules/raft/src/test/java/org/apache/ignite/raft/jraft/storage/impl/LogManagerTest.java
index 4049034280..6839fdafb7 100644
--- 
a/modules/raft/src/test/java/org/apache/ignite/raft/jraft/storage/impl/LogManagerTest.java
+++ 
b/modules/raft/src/test/java/org/apache/ignite/raft/jraft/storage/impl/LogManagerTest.java
@@ -21,6 +21,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertNotSame;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.util.ArrayList;
@@ -454,4 +455,23 @@ public class LogManagerTest extends BaseStorageTest {
         assertEquals("localhost:8081,localhost:8082", 
lastEntry.getOldConf().toString());
     }
 
+    @Test
+    public void testLastLogIdWhenShutdown() throws Exception {
+        mockAddEntries();
+        assertEquals(1, this.logManager.getFirstLogIndex());
+        assertEquals(10, this.logManager.getLastLogIndex());
+        this.logManager.shutdown();
+        Exception e = assertThrows(IllegalStateException.class, () -> 
this.logManager.getLastLogId(true));
+        assertEquals("Node is shutting down", e.getMessage());
+    }
+
+    @Test
+    public void testLastLogIndexWhenShutdown() throws Exception {
+        mockAddEntries();
+        assertEquals(1, this.logManager.getFirstLogIndex());
+        assertEquals(10, this.logManager.getLastLogIndex());
+        this.logManager.shutdown();
+        Exception e = assertThrows(IllegalStateException.class, () -> 
this.logManager.getLastLogIndex(true));
+        assertEquals("Node is shutting down", e.getMessage());
+    }
 }

Reply via email to