@edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "DCN_NULLPOINTER_EXCEPTION",
      justification = "HDFS-4380")
  private HasNext prepareReader() {
    if (reader != null) {
      if (state != null && state != WALTailingReader.State.NORMAL) {
        // reset before reading
        LOG.debug("Reset reader {} to pos {}, reset compression={}", currentPath,
          currentPositionOfEntry, state.resetCompression());
        try {
          resetReader();
          return HasNext.YES;
        } catch (IOException e) {
          LOG.warn("Failed to reset reader {} to pos {}, reset compression={}", currentPath,
            currentPositionOfEntry, state.resetCompression(), e);
          // just leave the state as is, and try resetting next time
          return HasNext.RETRY;
        }
      } else {
        return HasNext.YES;
      }
    }
    // try open next WAL file
    PriorityBlockingQueue<Path> queue = logQueue.getQueue(walGroupId);
    Path nextPath = queue.peek();
    if (nextPath == null) {
      LOG.debug("No more WAL files in queue");
      // no more files in queue, this could happen for recovered queue, or for a wal group of a
      // sync replication peer which has already been transited to DA or S.
      setCurrentPath(null);
      return HasNext.NO;
    }
    setCurrentPath(nextPath);
    // we need to test this prior to create the reader. If not, it is possible that, while
    // opening the file, the file is still being written so its header is incomplete and we get
    // a header EOF, but then while we test whether it is still being written, we have already
    // flushed the data out and we consider it is not being written, and then we just skip over
    // file, then we will lose the data written after opening...
    boolean beingWritten = walFileLengthProvider.getLogFileSizeIfBeingWritten(nextPath).isPresent();
    LOG.debug("Creating new reader {}, startPosition={}, beingWritten={}", nextPath,
      currentPositionOfEntry, beingWritten);
    try {
      reader = WALFactory.createTailingReader(fs, nextPath, conf,
        currentPositionOfEntry > 0 ? currentPositionOfEntry : -1);
      return HasNext.YES;
    } catch (WALHeaderEOFException e) {
      if (!eofAutoRecovery) {
        // if we do not enable EOF auto recovery, just let the upper layer retry
        // the replication will be stuck usually, and need to be fixed manually
        return HasNext.RETRY;
      }
      // we hit EOF while reading the WAL header, usually this means we can just skip over this
      // file, but we need to be careful that whether this file is still being written, if so we
      // should retry instead of skipping.
      LOG.warn("EOF while trying to open WAL reader for path: {}, startPosition={}", nextPath,
        currentPositionOfEntry, e);
      if (beingWritten) {
        // just retry as the file is still being written, maybe next time we could read
        // something
        return HasNext.RETRY;
      } else {
        // the file is not being written so we are safe to just skip over it
        dequeueCurrentLog();
        return HasNext.RETRY_IMMEDIATELY;
      }
    } catch (LeaseNotRecoveredException e) {
      // HBASE-15019 the WAL was not closed due to some hiccup.
      LOG.warn("Try to recover the WAL lease " + nextPath, e);
      AbstractFSWALProvider.recoverLease(conf, nextPath);
      return HasNext.RETRY;
    } catch (IOException | NullPointerException e) {
      // For why we need to catch NPE here, see HDFS-4380 for more details
      LOG.warn("Failed to open WAL reader for path: {}", nextPath, e);
      return HasNext.RETRY;
    }
  }
Returns the {@link Path} of the current WAL
hbase-server/src/main/java/org/apache/hadoop/hbase/replication/regionserver/WALEntryStream.java