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

com.scalar.dl.ledger.server.GateKeeper Maven / Gradle / Ivy

package com.scalar.dl.ledger.server;

import static java.util.concurrent.TimeUnit.NANOSECONDS;

import java.util.concurrent.TimeUnit;
import javax.annotation.concurrent.GuardedBy;
import javax.annotation.concurrent.ThreadSafe;

/** A gatekeeper that manages the front gate of the server that processes requests. */
@ThreadSafe
public class GateKeeper {

  @GuardedBy("this")
  private boolean isOpen;

  @GuardedBy("this")
  private int numOutstandingRequests;

  public GateKeeper() {
    isOpen = true;
  }

  /** Opens the gate to allow incoming requests to be processed. */
  public synchronized void open() {
    isOpen = true;
    notifyAll();
  }

  /**
   * Closes the gate to disallow incoming requests to be processed. After this call returns, new
   * requests are rejected. Note that this method will not wait for outstanding requests to finish
   * before returning. awaitDrained(long, TimeUnit) needs to be called to wait for outstanding
   * requests to finish.
   */
  public synchronized void close() {
    isOpen = false;
  }

  /**
   * Returns if the gate is open or not.
   *
   * @return true if the gate is open
   */
  public synchronized boolean isOpen() {
    return isOpen;
  }

  /**
   * Returns the number of outstanding requests.
   *
   * @return the number of outstanding requests
   */
  public synchronized int getNumOutstandingRequests() {
    return numOutstandingRequests;
  }

  /**
   * Waits for the server to finish outstanding requests, giving up if the timeout is reached.
   *
   * @param timeout the maximum time to wait
   * @param unit the time unit of the timeout argument
   * @return true if the server finishes outstanding requests and false otherwise
   */
  public synchronized boolean awaitDrained(long timeout, TimeUnit unit) {
    boolean interrupted = false;
    try {
      long timeoutNanos = unit.toNanos(timeout);
      long endTimeNanos = System.nanoTime() + timeoutNanos;
      while (!isOpen
          && numOutstandingRequests > 0
          && (timeoutNanos = endTimeNanos - System.nanoTime()) > 0) {
        try {
          NANOSECONDS.timedWait(this, timeoutNanos);
        } catch (InterruptedException ignored) {
          interrupted = true;
        }
      }
      return numOutstandingRequests == 0;
    } finally {
      if (interrupted) {
        Thread.currentThread().interrupt();
      }
    }
  }

  /**
   * Lets a new request in to process it in the server if the gate is open. If the gate is closed,
   * waits until the gate is open.
   */
  public synchronized void letIn() {
    boolean interrupted = false;
    try {
      while (!isOpen) {
        try {
          wait();
        } catch (InterruptedException ignored) {
          interrupted = true;
        }
      }
      numOutstandingRequests++;
    } finally {
      if (interrupted) {
        Thread.currentThread().interrupt();
      }
    }
  }

  /** Lets a processed request out. */
  public synchronized void letOut() {
    if (--numOutstandingRequests == 0) {
      notifyAll();
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy