All Downloads are FREE. Search and download functionalities are using the official Maven repository.

tachyon.master.journal.JournalTailerThread Maven / Gradle / Ivy

/*
 * Licensed to the University of California, Berkeley under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for additional information regarding
 * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance with the License. You may obtain a
 * copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */

package tachyon.master.journal;

import java.io.IOException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Preconditions;

import tachyon.Constants;
import tachyon.conf.TachyonConf;
import tachyon.master.Master;
import tachyon.master.MasterContext;
import tachyon.util.CommonUtils;

/**
 * This thread continually tails the journal and applies it to the master, until the master
 * initiates the shutdown of the thread.
 */
public final class JournalTailerThread extends Thread {
  private static final Logger LOG = LoggerFactory.getLogger(Constants.LOGGER_TYPE);

  /** The master to apply the journal entries to. */
  private final Master mMaster;
  /** The journal to tail. */
  private final Journal mJournal;
  private final int mShutdownQuietWaitTimeMs;
  private final int mJournalTailerSleepTimeMs;
  /** This becomes true when the master initiates the shutdown. */
  private volatile boolean mInitiateShutdown = false;

  /** The {@link JournalTailer} that this thread uses to continually tail the journal. */
  private JournalTailer mJournalTailer = null;
  /** True if this thread is no longer running. */
  private boolean mStopped = false;

  /**
   * @param master the master to apply the journal entries to
   * @param journal the journal to tail
   */
  public JournalTailerThread(Master master, Journal journal) {
    mMaster = Preconditions.checkNotNull(master);
    mJournal = Preconditions.checkNotNull(journal);
    TachyonConf conf = MasterContext.getConf();
    mShutdownQuietWaitTimeMs = conf.getInt(
        Constants.MASTER_JOURNAL_TAILER_SHUTDOWN_QUIET_WAIT_TIME_MS);
    mJournalTailerSleepTimeMs = conf.getInt(Constants.MASTER_JOURNAL_TAILER_SLEEP_TIME_MS);
  }

  /**
   * Initiate the shutdown of this tailer thread.
   */
  public void shutdown() {
    LOG.info(mMaster.getServiceName() + ": Journal tailer shutdown has been initiated.");
    mInitiateShutdown = true;
  }

  /**
   * Initiate the shutdown of this tailer thread, and also wait for it to finish.
   */
  public void shutdownAndJoin() {
    shutdown();
    try {
      // Wait for the thread to finish.
      join();
    } catch (InterruptedException ie) {
      LOG.warn(mMaster.getServiceName() + ": stopping the journal tailer caused exception: "
          + ie.getMessage());
    }
  }

  /**
   * @return the {@link JournalTailer} that this thread last used to tail the journal. This will
   *         only return the {@link JournalTailer} if this thread is no longer running, to prevent
   *         concurrent access to the {@link JournalTailer}. Returns null if this thread has not yet
   *         used a {@link JournalTailer}, or if this thread is still running.
   */
  public JournalTailer getLatestJournalTailer() {
    if (mStopped) {
      return mJournalTailer;
    }
    return null;
  }

  @Override
  public void run() {
    LOG.info(mMaster.getServiceName() + ": Journal tailer started.");
    // Continually loop loading the checkpoint file, and then loading all completed files. The loop
    // only repeats when the checkpoint file is updated after it was read.
    while (!mInitiateShutdown) {
      try {
        // The start time (ms) for the initiated shutdown.
        long waitForShutdownStart = -1;

        // Load the checkpoint file.
        LOG.info(mMaster.getServiceName() + ": Waiting to load the checkpoint file.");
        mJournalTailer = new JournalTailer(mMaster, mJournal);
        while (!mJournalTailer.checkpointExists()) {
          CommonUtils.sleepMs(LOG, mJournalTailerSleepTimeMs);
          if (mInitiateShutdown) {
            LOG.info("Journal tailer has been shutdown while waiting to load the checkpoint file.");
            mStopped = true;
            return;
          }
        }
        LOG.info(mMaster.getServiceName() + ": Start loading the checkpoint file.");
        mJournalTailer.processJournalCheckpoint(true);
        LOG.info(mMaster.getServiceName() + ": Checkpoint file has been loaded.");

        // Continually process completed log files.
        while (mJournalTailer.isValid()) {
          if (mJournalTailer.processNextJournalLogFiles() > 0) {
            // Reset the shutdown timer.
            waitForShutdownStart = -1;
          } else {
            if (mInitiateShutdown) {
              if (waitForShutdownStart == -1) {
                waitForShutdownStart = CommonUtils.getCurrentMs();
              } else if ((CommonUtils.getCurrentMs()
                  - waitForShutdownStart) > mShutdownQuietWaitTimeMs) {
                // There have been no new logs for the quiet period. Shutdown now.
                LOG.info(mMaster.getServiceName()
                    + ": Journal tailer has been shutdown. No new logs for the quiet period.");
                mStopped = true;
                return;
              }
            }
            LOG.debug(mMaster.getServiceName()
                + ": The next complete log file does not exist yet. Sleeping and checking again.");
            CommonUtils.sleepMs(LOG, mJournalTailerSleepTimeMs);
          }
        }
        LOG.info(mMaster.getServiceName()
            + ": The checkpoint is out of date. Will reload the checkpoint file.");
        CommonUtils.sleepMs(LOG, mJournalTailerSleepTimeMs);
      } catch (IOException ioe) {
        // Log the error and continue the loop.
        LOG.error(ioe.getMessage());
      }
    }
    LOG.info(mMaster.getServiceName() + ": Journal tailer has been shutdown.");
    mStopped = true;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy