sig
  type t
  type limiter = Limiter.t
  module Infinite_or_finite :
    sig
      type 'a t = Infinite | Finite of 'a
      val bin_t :
        'Core_kernel.Std.Bin_prot.Type_class.t ->
        'Limiter.Infinite_or_finite.t Core_kernel.Std.Bin_prot.Type_class.t
      val bin_read_t :
        'Core_kernel.Std.Bin_prot.Read.reader ->
        'Limiter.Infinite_or_finite.t Core_kernel.Std.Bin_prot.Read.reader
      val __bin_read_t__ :
        'Core_kernel.Std.Bin_prot.Read.reader ->
        (int -> 'Limiter.Infinite_or_finite.t)
        Core_kernel.Std.Bin_prot.Read.reader
      val bin_reader_t :
        'Core_kernel.Std.Bin_prot.Type_class.reader ->
        'Limiter.Infinite_or_finite.t
        Core_kernel.Std.Bin_prot.Type_class.reader
      val bin_size_t :
        'Core_kernel.Std.Bin_prot.Size.sizer ->
        'Limiter.Infinite_or_finite.t Core_kernel.Std.Bin_prot.Size.sizer
      val bin_write_t :
        'Core_kernel.Std.Bin_prot.Write.writer ->
        'Limiter.Infinite_or_finite.t Core_kernel.Std.Bin_prot.Write.writer
      val bin_writer_t :
        'Core_kernel.Std.Bin_prot.Type_class.writer ->
        'Limiter.Infinite_or_finite.t
        Core_kernel.Std.Bin_prot.Type_class.writer
      val t_of_sexp :
        (Sexplib.Sexp.t -> 'a) ->
        Sexplib.Sexp.t -> 'Limiter.Infinite_or_finite.t
      val sexp_of_t :
        ('-> Sexplib.Sexp.t) ->
        'Limiter.Infinite_or_finite.t -> Sexplib.Sexp.t
    end
  module Token_bucket :
    sig
      type t = private Limiter.limiter
      val create_exn :
        now:Time.t ->
        burst_size:float ->
        sustained_rate_per_sec:float ->
        ?initial_bucket_level:float -> unit -> Limiter.Token_bucket.t
      val try_take :
        Limiter.Token_bucket.t ->
        now:Time.t ->
        float -> [ `Asked_for_more_than_bucket_size | `Taken | `Unable ]
    end
  module Throttle :
    sig
      type t = private Limiter.limiter
      val create_exn :
        now:Time.t -> max_concurrent_jobs:int -> Limiter.Throttle.t
      val try_start_job :
        Limiter.Throttle.t ->
        now:Time.t -> [ `Max_concurrent_jobs_running | `Start ]
      val finish_job : Limiter.Throttle.t -> now:Time.t -> unit
    end
  module Throttled_rate_limiter :
    sig
      type t = private Limiter.limiter
      val create_exn :
        now:Time.t ->
        burst_size:int ->
        sustained_rate_per_sec:float ->
        max_concurrent_jobs:int -> Limiter.Throttled_rate_limiter.t
      val try_start_job :
        Limiter.Throttled_rate_limiter.t ->
        now:Time.t ->
        [ `Max_concurrent_jobs_running
        | `Start
        | `Unable_until_at_least of Time.t ]
      val finish_job : Limiter.Throttled_rate_limiter.t -> now:Time.t -> unit
    end
  val bucket_size : Limiter.t -> float
  val in_bucket : Limiter.t -> now:Time.t -> float
  val in_hopper :
    Limiter.t -> now:Time.t -> float Limiter.Infinite_or_finite.t
  val in_flight : Limiter.t -> now:Time.t -> float
  val in_limiter :
    Limiter.t -> now:Time.t -> float Limiter.Infinite_or_finite.t
  val in_system :
    Limiter.t -> now:Time.t -> float Limiter.Infinite_or_finite.t
  val hopper_to_bucket_rate_per_sec :
    Limiter.t -> float Limiter.Infinite_or_finite.t
  module Expert :
    sig
      val create_exn :
        now:Time.t ->
        hopper_to_bucket_rate_per_sec:float Limiter.Infinite_or_finite.t ->
        bucket_size:float ->
        initial_bucket_level:float ->
        initial_hopper_level:float Limiter.Infinite_or_finite.t -> Limiter.t
      val tokens_may_be_available_when :
        Limiter.t ->
        now:Time.t ->
        float ->
        [ `At of Time.t
        | `Never_because_greater_than_bucket_size
        | `When_return_to_hopper_is_called ]
      val try_take :
        Limiter.t ->
        now:Time.t ->
        float -> [ `Asked_for_more_than_bucket_size | `Taken | `Unable ]
      val return_to_hopper : Limiter.t -> now:Time.t -> float -> unit
      val set_hopper_to_bucket_rate_per_sec_exn :
        Limiter.t -> now:Time.t -> float Limiter.Infinite_or_finite.t -> unit
      val set_token_target_level_exn :
        Limiter.t -> now:Time.t -> float Limiter.Infinite_or_finite.t -> unit
      val set_bucket_size_exn : Limiter.t -> now:Time.t -> float -> unit
    end
  val invariant : t Core_kernel.Invariant_intf.inv
  val sexp_of_t : Limiter.t -> Sexplib.Sexp.t
  val sexp_of_limiter : Limiter.limiter -> Sexplib.Sexp.t
end