109.24.00

- Reworked the `Throttle` module.

  Made both `Throttle.t` and `Throttle.Sequencer.t` instances of the
  same type, using a phantom type to distinguish them.  Removed all
  `Throttle.Sequencer` functions -- one can now use the `Throttle`
  functions directly.

  Added new functions:

  ```ocaml
  (*** [max_concurrent_jobs t] returns the maximum number of jobs that [t] will run
      concurrently. *)
  val max_concurrent_jobs : (_, _) t_ -> int

  (*** [num_jobs_running t] returns the number of jobs that [t] is currently running.  It
      is guaranteed that if [num_jobs_running t < max_concurrent_jobs t] then
      [num_jobs_waiting_to_start t = 0].  That is, the throttle always uses its maximum
      concurrency if possible. *)
  val num_jobs_running : (_, _) t_ -> int

  (*** [num_jobs_waiting_to_start t] returns the number of jobs that have been [enqueue]d but
      have not yet started. *)
  val num_jobs_waiting_to_start : (_ , _) t_ -> int

  (*** [capacity_available t] becomes determined the next time that [t] has fewer than
      [max_concurrent_jobs t] running, and hence an [enqueue]d job would start
      immediately. *)
  val capacity_available : (_, _) t_ -> unit Deferred.t

  Replaced the `Pipe` used inside a `Throttle` with a `Queue`, and
  simplified the implementation.  This fixed a bug in
  `num_jobs_waiting_to_start`, which could have missed a job that was
  not in the pipe but had not started.
  ```