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

com.hubspot.singularity.async.AsyncSemaphoreBuilder Maven / Gradle / Ivy

package com.hubspot.singularity.async;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeoutException;
import java.util.function.Supplier;

public class AsyncSemaphoreBuilder {
  private final PermitSource permitSource;
  private final ScheduledExecutorService flushingExecutor;

  private int queueSize = -1;
  private Supplier queueRejectionThreshold = () -> -1;
  private Supplier timeoutExceptionSupplier = TimeoutException::new;
  private boolean flushQueuePeriodically = false;

  AsyncSemaphoreBuilder(
    PermitSource permitSource,
    ScheduledExecutorService flushingExecutor
  ) {
    this.permitSource = permitSource;
    this.flushingExecutor = flushingExecutor;
  }

  /**
   * Sets the maximum size of the queue. Note that this should be larger than any
   * desired queueRejectionThreshold.
   */
  public AsyncSemaphoreBuilder withQueueSize(int queueSize) {
    this.queueSize = queueSize;
    return this;
  }

  /**
   * Sets a dynamic rejection threshold. If -1, the queue size is used
   * to reject requests. Otherwise, this number is the effective
   * number of allowed tasks.
   */
  public AsyncSemaphoreBuilder withQueueRejectionThreshold(
    Supplier queueRejectionThreshold
  ) {
    this.queueRejectionThreshold = queueRejectionThreshold;
    return this;
  }

  /**
   * Sets the type of the exception to be thrown when the {@code callWithQueueTimeout}
   * method is called and the call is queued for longer than the timeout.
   */
  public AsyncSemaphoreBuilder withTimeoutExceptionSupplier(
    Supplier timeoutExceptionSupplier
  ) {
    this.timeoutExceptionSupplier = timeoutExceptionSupplier;
    return this;
  }

  /**
   * If set to a positive value, will flush the internal queue every once a second
   * used in cases where the async semaphore is used in batch processing to avoid a
   * rare case when work can become stuck in the queue and never complete.
   * @param flushQueuePeriodically
   * @return
   */
  public AsyncSemaphoreBuilder setFlushQueuePeriodically(boolean flushQueuePeriodically) {
    this.flushQueuePeriodically = flushQueuePeriodically;
    return this;
  }

  public  AsyncSemaphore build() {
    return new AsyncSemaphore<>(
      permitSource,
      queueSize == -1
        ? new ConcurrentLinkedQueue<>()
        : new ArrayBlockingQueue<>(queueSize),
      queueRejectionThreshold,
      timeoutExceptionSupplier,
      flushQueuePeriodically,
      flushingExecutor
    );
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy