private Pair<WALTailingReader.State, Boolean> readNextEntryAndRecordReaderPosition() {
    OptionalLong fileLength;
    if (logQueue.getQueueSize(walGroupId) > 1) {
      // if there are more than one files in queue, although it is possible that we are
      // still trying to write the trailer of the file and it is not closed yet, we can
      // make sure that we will not write any WAL entries to it any more, so it is safe
      // to just let the upper layer try to read the whole file without limit
      fileLength = OptionalLong.empty();
    } else {
      // if there is only one file in queue, check whether it is still being written to
      // we must call this before actually reading from the reader, as this method will acquire the
      // rollWriteLock. This is very important, as we will enqueue the new WAL file in postLogRoll,
      // and before this happens, we could have already finished closing the previous WAL file. If
      // we do not acquire the rollWriteLock and return whether the current file is being written
      // to, we may finish reading the previous WAL file and start to read the next one, before it
      // is enqueued into the logQueue, thus lead to an empty logQueue and make the shipper think
      // the queue is already ended and quit. See HBASE-28114 and related issues for more details.
      // in the future, if we want to optimize the logic here, for example, do not call this method
      // every time, or do not acquire rollWriteLock in the implementation of this method, we need
      // to carefully review the optimized implementation
      fileLength = walFileLengthProvider.getLogFileSizeIfBeingWritten(currentPath);
    }
    WALTailingReader.Result readResult = reader.next(fileLength.orElse(-1));
    long readerPos = readResult.getEntryEndPos();
    Entry readEntry = readResult.getEntry();
    if (readResult.getState() == WALTailingReader.State.NORMAL) {
      LOG.trace("reading entry: {} ", readEntry);
      metrics.incrLogEditsRead();
      metrics.incrLogReadInBytes(readerPos - currentPositionOfEntry);
      // record current entry and reader position
      currentEntry = readResult.getEntry();
      this.currentPositionOfReader = readerPos;
    } else {
      LOG.trace("reading entry failed with: {}", readResult.getState());
      // set current entry to null
      currentEntry = null;
      try {
        this.currentPositionOfReader = reader.getPosition();
      } catch (IOException e) {
        LOG.warn("failed to get current position of reader", e);
        if (readResult.getState().resetCompression()) {
          return Pair.newPair(WALTailingReader.State.ERROR_AND_RESET_COMPRESSION,
            fileLength.isPresent());
        }
      }
    }
    return Pair.newPair(readResult.getState(), fileLength.isPresent());
  }
Returns whether the file is opened for writing.
hbase-server/src/main/java/org/apache/hadoop/hbase/replication/regionserver/WALEntryStream.java