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

edu.byu.hbll.scheduler.PeriodicSchedule Maven / Gradle / Ivy

package edu.byu.hbll.scheduler;

import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import lombok.Getter;

/**
 * A schedule that only runs periodically based on a fixed period.
 *
 * @author Charles Draper
 */
public class PeriodicSchedule extends BaseSchedule {

  /** The length of time between runs. */
  @Getter protected final Duration period;

  /** Whether or not this is marked as fixed rate. */
  @Getter protected final boolean fixedRate;

  private PeriodicSchedule(Builder builder) {
    super(builder);
    this.period = builder.period;
    this.fixedRate = builder.fixedRate;
  }

  /**
   * Creates a new builder with the given period.
   *
   * @param period the period of time between runs
   * @return the builder
   */
  public static PeriodicSchedule.Builder builder(Duration period) {
    return new PeriodicSchedule.Builder(period);
  }

  /**
   * Creates a new schedule based on the given period.
   *
   * @param period the period of time between runs
   * @return a new schedule based on the given period
   */
  public static PeriodicSchedule of(Duration period) {
    return builder(period).build();
  }

  /**
   * Creates a new schedule based on the given period.
   *
   * @param periodInMillis the period of time between runs in milliseconds
   * @return a new schedule based on the given period
   */
  public static PeriodicSchedule ofMillis(long periodInMillis) {
    return builder(Duration.ofMillis(periodInMillis)).build();
  }

  /**
   * Creates a new schedule based on the given period.
   *
   * @param periodInSeconds the period of time between runs in seconds
   * @return a new schedule based on the given period
   */
  public static PeriodicSchedule ofSeconds(long periodInSeconds) {
    return builder(Duration.ofSeconds(periodInSeconds)).build();
  }

  /**
   * Creates a new schedule based on the given period.
   *
   * @param periodInMinutes the period of time between runs in minutes
   * @return a new schedule based on the given period
   */
  public static PeriodicSchedule ofMinutes(long periodInMinutes) {
    return builder(Duration.ofMinutes(periodInMinutes)).build();
  }

  /**
   * Creates a new schedule based on the given period.
   *
   * @param periodInHours the period of time between runs in hours
   * @return a new schedule based on the given period
   */
  public static PeriodicSchedule ofHours(long periodInHours) {
    return builder(Duration.ofHours(periodInHours)).build();
  }

  @Override
  public Instant next(ScheduledTask task, Instant start, Instant from) {
    if (task.getNumScheduled() == 0) {
      return start;
    } else if (fixedRate) {
      // calculate the next period number
      long nextPeriod = (from.toEpochMilli() - start.toEpochMilli()) / period.toMillis() + 1;

      // calculate next based on the next period number
      Instant next = start.plus(nextPeriod * period.toMillis(), ChronoUnit.MILLIS);
      return next;
    } else {
      return from.plus(period);
    }
  }

  /**
   * Builder for {@link PeriodicSchedule}.
   *
   * @author Charles Draper
   */
  public static class Builder extends BaseSchedule.Builder {

    private Duration period;
    private boolean fixedRate;

    /**
     * Creates a new builder with the given period.
     *
     * @param period the period of time between runs
     */
    public Builder(Duration period) {
      this.period = period;
    }

    /**
     * Sets whether or not the next run of a periodic task should be calculated on fixed intervals
     * vs waiting until the task terminates. (default: false)
     *
     * @param fixedRate whether or not to use a fixed rate
     * @return this
     */
    public Builder fixedRate(boolean fixedRate) {
      this.fixedRate = fixedRate;
      return this;
    }

    public PeriodicSchedule build() {
      return new PeriodicSchedule(this);
    }

    @Override
    protected Builder getThis() {
      return this;
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy