Repository: sofastack/sofa-jraft (Java)

Issue:
在使用 sofa-bolt 的情况下， PingRequestProcessor  是否有必要设置单独的 Executor？
PingRequestProcessor 中 executor() 返回 null, 则会使用 com.alipay.remoting.ProcessorManager#getDefaultExecutor(); 当这个线程池满了，或队列中比较多数据时，会影响 PingRequestProcessor 的执行，从而影响集群的状态。 那么 PingRequestProcessor  是否有必要设置单独的 Executor？



Discussion: 遇到实际问题了吗？ PingRequestProcessor 没有指定 executor，但是其他的所有 processor 都有指定 executor，也就是基本相当于 PingRequestProcessor 独占了 default executor
com.alipay.remoting.ProcessorManager#getDefaultExecutor(); 还被用于处理 bolt rpc 超时，如果有大量RPC超时，default executor 有堆积时，会造成心跳也超时。
我们可以为这个[方法](https://github.com/sofastack/sofa-jraft/blob/59853a78d054d0faf52e3ee10fa685d0d4a1783a/jraft-core/src/main/java/com/alipay/sofa/jraft/rpc/RaftRpcServerFactory.java#L95)增加一个 pingExecutor 参数

当然，我还希望原有方法签名保留，它会是这样：

```
public static void addRaftRequestProcessors(final RpcServer rpcServer, final Executor raftExecutor,
                                                final Executor cliExecutor) {
addRaftRequestProcessors(rpcServer, raftExecutor, null, cliExecutor)
}
```

也就说，默认的 ping executor 就是 null，对此你有其他的意见吗？
> 我们可以为这个[方法](https://github.com/sofastack/sofa-jraft/blob/59853a78d054d0faf52e3ee10fa685d0d4a1783a/jraft-core/src/main/java/com/alipay/sofa/jraft/rpc/RaftRpcServerFactory.java#L95)增加一个 pingExecutor 参数
> 
> 当然，我还希望原有方法签名保留，它会是这样：
> 
> ```
> public static void addRaftRequestProcessors(final RpcServer rpcServer, final Executor raftExecutor,
>                                                 final Executor cliExecutor) {
> addRaftRequestProcessors(rpcServer, raftExecutor, null, cliExecutor)
> }
> ```
> 
> 也就说，默认的 ping executor 就是 null，对此你有其他的意见吗？

没有，那我按这个方法改一下。
感谢，我会把这个 pr 加到新的 release 中



Fix (patch):
diff --git a/jraft-core/src/main/java/com/alipay/sofa/jraft/rpc/RaftRpcServerFactory.java b/jraft-core/src/main/java/com/alipay/sofa/jraft/rpc/RaftRpcServerFactory.java
index 38dc6b614..3887fac43 100644
--- a/jraft-core/src/main/java/com/alipay/sofa/jraft/rpc/RaftRpcServerFactory.java
+++ b/jraft-core/src/main/java/com/alipay/sofa/jraft/rpc/RaftRpcServerFactory.java
@@ -71,8 +71,22 @@ public static RpcServer createRaftRpcServer(final Endpoint endpoint) {
      */
     public static RpcServer createRaftRpcServer(final Endpoint endpoint, final Executor raftExecutor,
                                                 final Executor cliExecutor) {
+        return createRaftRpcServer(endpoint, raftExecutor, cliExecutor, null);
+    }
+
+    /**
+     * Creates a raft RPC server with executors to handle requests.
+     *
+     * @param endpoint      server address to bind
+     * @param raftExecutor  executor to handle RAFT requests.
+     * @param cliExecutor   executor to handle CLI service requests.
+     * @param pingExecutor  executor to handle ping requests.
+     * @return a rpc server instance
+     */
+    public static RpcServer createRaftRpcServer(final Endpoint endpoint, final Executor raftExecutor,
+                                                final Executor cliExecutor, final Executor pingExecutor) {
         final RpcServer rpcServer = RpcFactoryHelper.rpcFactory().createRpcServer(endpoint);
-        addRaftRequestProcessors(rpcServer, raftExecutor, cliExecutor);
+        addRaftRequestProcessors(rpcServer, raftExecutor, cliExecutor, pingExecutor);
         return rpcServer;
     }
 
@@ -94,6 +108,19 @@ public static void addRaftRequestProcessors(final RpcServer rpcServer) {
      */
     public static void addRaftRequestProcessors(final RpcServer rpcServer, final Executor raftExecutor,
                                                 final Executor cliExecutor) {
+        addRaftRequestProcessors(rpcServer, raftExecutor, cliExecutor, null);
+    }
+
+    /**
+     * Adds RAFT and CLI service request processors.
+     *
+     * @param rpcServer    rpc server instance
+     * @param raftExecutor executor to handle RAFT requests.
+     * @param cliExecutor  executor to handle CLI service requests.
+     * @param pingExecutor executor to handle ping requests.
+     */
+    public static void addRaftRequestProcessors(final RpcServer rpcServer, final Executor raftExecutor,
+                                                final Executor cliExecutor, final Executor pingExecutor) {
         // raft core processors
         final AppendEntriesRequestProcessor appendEntriesRequestProcessor = new AppendEntriesRequestProcessor(
             raftExecutor);
@@ -102,7 +129,7 @@ public static void addRaftRequestProcessors(final RpcServer rpcServer, final Exe
         rpcServer.registerProcessor(new GetFileRequestProcessor(raftExecutor));
         rpcServer.registerProcessor(new InstallSnapshotRequestProcessor(raftExecutor));
         rpcServer.registerProcessor(new RequestVoteRequestProcessor(raftExecutor));
-        rpcServer.registerProcessor(new PingRequestProcessor());
+        rpcServer.registerProcessor(new PingRequestProcessor(pingExecutor));
         rpcServer.registerProcessor(new TimeoutNowRequestProcessor(raftExecutor));
         rpcServer.registerProcessor(new ReadIndexRequestProcessor(raftExecutor));
         // raft cli service
diff --git a/jraft-core/src/main/java/com/alipay/sofa/jraft/rpc/impl/PingRequestProcessor.java b/jraft-core/src/main/java/com/alipay/sofa/jraft/rpc/impl/PingRequestProcessor.java
index 89f86032d..085837112 100644
--- a/jraft-core/src/main/java/com/alipay/sofa/jraft/rpc/impl/PingRequestProcessor.java
+++ b/jraft-core/src/main/java/com/alipay/sofa/jraft/rpc/impl/PingRequestProcessor.java
@@ -22,6 +22,8 @@
 import com.alipay.sofa.jraft.rpc.RpcRequests.PingRequest;
 import com.alipay.sofa.jraft.util.RpcFactoryHelper;
 
+import java.util.concurrent.Executor;
+
 /**
  * Ping request processor.
  *
@@ -30,6 +32,12 @@
  */
 public class PingRequestProcessor implements RpcProcessor<PingRequest> {
 
+    private final Executor executor;
+
+    public PingRequestProcessor(Executor executor) {
+        this.executor = executor;
+    }
+
     @Override
     public void handleRequest(final RpcContext rpcCtx, final PingRequest request) {
         rpcCtx.sendResponse( //
@@ -42,4 +50,9 @@ public void handleRequest(final RpcContext rpcCtx, final PingRequest request) {
     public String interest() {
         return PingRequest.class.getName();
     }
+
+    @Override
+    public Executor executor() {
+        return this.executor;
+    }
 }