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

org.apache.hadoop.hive.ql.lock.CompileLock Maven / Gradle / Ivy

There is a newer version: 4.0.1
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) 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 org.apache.hadoop.hive.ql.lock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import org.apache.hadoop.hive.ql.ErrorMsg;

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

/**
 * Encapsulates HS2 compile lock logic.
 */
public final class CompileLock implements AutoCloseable {

  private static final Logger LOG = LoggerFactory.getLogger(CompileLock.class);

  private static final String LOCK_ACQUIRED_MSG = "Acquired the compile lock.";
  private static final String WAIT_LOCK_ACQUIRE_MSG = "Waiting to acquire compile lock: ";

  private final Lock underlying;
  private final long defaultTimeout;

  private final String command;
  private boolean isLocked = false;

  CompileLock(Lock underlying, long timeout, String command) {
    this.underlying = underlying;
    this.command = command;
    this.defaultTimeout = timeout;
  }

  /**
   * Acquires the compile lock. If the compile lock wait timeout is configured,
   * it will acquire the lock if it is not held by another thread within the given
   * waiting time.
   *
   * @return {@code true} if the lock was successfully acquired,
   * or {@code false} if compile lock wait timeout is configured and
   * either the waiting time elapsed before the lock could be acquired
   * or the current thread was interrupted.
   */
  public boolean tryAcquire() {
    return tryAcquire(defaultTimeout, TimeUnit.SECONDS);
  }

  private boolean tryAcquire(long timeout, TimeUnit unit) {
    // First shot without waiting.
    try {
      if (underlying.tryLock(0, unit)) {
        LOG.debug(LOCK_ACQUIRED_MSG);
        return acquired();
      }
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
      LOG.debug("Interrupted Exception ignored", e);
      return failedToAcquire();
    }

    // If the first shot fails, then we log the waiting messages.
    if (LOG.isDebugEnabled()) {
      LOG.debug(WAIT_LOCK_ACQUIRE_MSG + command);
    }

    if (timeout > 0) {
      try {
        if (!underlying.tryLock(timeout, unit)) {
          LOG.error(ErrorMsg.COMPILE_LOCK_TIMED_OUT.getErrorCodedMsg() + ": " + command);
          return failedToAcquire();
        }
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        LOG.debug("Interrupted Exception ignored", e);
        return failedToAcquire();
      }
    } else {
      underlying.lock();
    }

    LOG.debug(LOCK_ACQUIRED_MSG);
    return acquired();
  }

  private boolean acquired() {
    return locked(true);
  }

  private boolean failedToAcquire() {
    return locked(false);
  }

  private boolean locked(boolean isLocked) {
    this.isLocked  = isLocked;
    return isLocked;
  }

  /**
   * Releases the compile lock.
   *
   * An underlying {@code Lock} implementation will usually impose restrictions on which
   * thread can release a lock (typically only the holder of the lock can release it)
   * and may throw an (unchecked) exception if the restriction is violated.
   */
  public void release() {
    underlying.unlock();
    isLocked = false;
  }

  @Override
  public void close() {
    if (isLocked) {
      release();
    }
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy