private RaftClientReply doRead(
      RaftGroupId gid, IConsensusRequest readRequest, boolean linearizable) throws Exception {
    final RaftClientRequest.Type readType =
        linearizable
            ? RaftClientRequest.readRequestType()
            : RaftClientRequest.staleReadRequestType(-1);
    final RequestMessage requestMessage = new RequestMessage(readRequest);
    final RaftClientRequest request = buildRawRequest(gid, requestMessage, readType);

    RaftClientReply reply;
    try (AutoCloseable ignored =
        RatisMetricsManager.getInstance().startReadTimer(consensusGroupType)) {
      reply =
          Retriable.attempt(
              () -> {
                try {
                  return server.get().submitClientRequest(request);
                } catch (
                    IOException
                        ioe) { // IOE indicates some unexpected errors, say StatusRuntimeException
                  if (ioe.getCause() instanceof StatusRuntimeException) {
                    // StatusRuntimeException will be thrown if the leader is offline (gRPC cannot
                    // connect to the peer)
                    // We can still retry in case it's a temporary network partition.
                    return RaftClientReply.newBuilder()
                        .setClientId(localFakeId)
                        .setServerId(server.get().getId())
                        .setGroupId(request.getRaftGroupId())
                        .setException(
                            new ReadIndexException(
                                "internal GRPC connection error:", ioe.getCause()))
                        .setSuccess(false)
                        .build();
                  } else {
                    throw ioe;
                  }
                }
              },
              readRetryPolicy,
              () -> readRequest,
              logger);
    }

    // rethrow the exception if the reply is not successful
    if (!reply.isSuccess()) {
      throw reply.getException();
    }

    return reply;
  }
return a success raft client reply or throw an Exception
iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/ratis/RatisConsensus.java