import { resolver } from "@rocicorp/resolver";
import { assert } from "../../../../shared/src/asserts.js";
const TARGET_UTILIZATION = 0.6;
class DrainCoordinator {
  #draining = resolver();
  #nextDrainTime = 0;
  #timeout = resolver();
  #timeoutID;
  get draining() {
    return this.#draining.promise;
  }
  shouldDrain() {
    return this.#nextDrainTime && this.#nextDrainTime <= Date.now();
  }
  drainNextIn(interval) {
    this.#draining.resolve("draining");
    interval /= TARGET_UTILIZATION;
    const now = Date.now();
    assert(
      this.#nextDrainTime <= now,
      `drainNextIn() should only be called if shouldDrain()`
    );
    this.#nextDrainTime = now + interval;
    clearTimeout(this.#timeoutID);
    this.#timeoutID = setTimeout(() => {
      this.#timeout.resolve();
      this.#timeout = resolver();
    }, interval + FORCE_DRAIN_PADDING);
  }
  get forceDrainTimeout() {
    return this.#timeout.promise;
  }
  // Exposed for testing.
  get nextDrainTime() {
    return this.#nextDrainTime;
  }
}
const FORCE_DRAIN_PADDING = 2;
export {
  DrainCoordinator
};
//# sourceMappingURL=drain-coordinator.js.map
