com.jnape.palatable.lambda.functions.builtin.fn4

## Class RateLimit<A>

- java.lang.Object
- - com.jnape.palatable.lambda.functions.builtin.fn4.RateLimit<A>

- Type Parameters:
    `A` - the `Iterable` element type
  All Implemented Interfaces:
    Fn1<Fn0<Instant>,Fn1<Long,Fn1<Duration,Fn1<Iterable<A>,Iterable<A>>>>>, Fn2<Fn0<Instant>,Long,Fn1<Duration,Fn1<Iterable<A>,Iterable<A>>>>, Fn3<Fn0<Instant>,Long,Duration,Fn1<Iterable<A>,Iterable<A>>>, Fn4<Fn0<Instant>,Long,Duration,Iterable<A>,Iterable<A>>, Applicative<Fn1<Long,Fn1<Duration,Fn1<Iterable<A>,Iterable<A>>>>,Fn1<Fn0<Instant>,?>>, Cartesian<Fn0<Instant>,Fn1<Long,Fn1<Duration,Fn1<Iterable<A>,Iterable<A>>>>,Fn1<?,?>>, Cocartesian<Fn0<Instant>,Fn1<Long,Fn1<Duration,Fn1<Iterable<A>,Iterable<A>>>>,Fn1<?,?>>, Contravariant<Fn0<Instant>,Profunctor<?,Fn1<Long,Fn1<Duration,Fn1<Iterable<A>,Iterable<A>>>>,Fn1<?,?>>>, Functor<Fn1<Long,Fn1<Duration,Fn1<Iterable<A>,Iterable<A>>>>,Fn1<Fn0<Instant>,?>>, Profunctor<Fn0<Instant>,Fn1<Long,Fn1<Duration,Fn1<Iterable<A>,Iterable<A>>>>,Fn1<?,?>>, Monad<Fn1<Long,Fn1<Duration,Fn1<Iterable<A>,Iterable<A>>>>,Fn1<Fn0<Instant>,?>>, MonadReader<Fn0<Instant>,Fn1<Long,Fn1<Duration,Fn1<Iterable<A>,Iterable<A>>>>,Fn1<Fn0<Instant>,?>>, MonadRec<Fn1<Long,Fn1<Duration,Fn1<Iterable<A>,Iterable<A>>>>,Fn1<Fn0<Instant>,?>>, MonadWriter<Fn0<Instant>,Fn1<Long,Fn1<Duration,Fn1<Iterable<A>,Iterable<A>>>>,Fn1<Fn0<Instant>,?>>

      public final class RateLimit<A>
      extends Object
      implements Fn4<Fn0<Instant>,Long,Duration,Iterable<A>,Iterable<A>>

  Given an `Fn0` of `Instants` (presumably backed by a clock), a `limit`, a `Duration`, and an `Iterable` `as`, return an `Iterable` that iterates `as` according to the threshold specified by the limit per duration, using the `Fn0` to advance time.

  As an example, the following will print at most 10 elements per second:

       rateLimit(Clock.systemUTC()::instant, 10L, Duration.ofSeconds(1), iterate(x -> x + 1, 1))
           .forEach(System.out::println);

  Currying allows different rate limits to be combined naturally:

       Iterable<Integer> elements = iterate(x -> x + 1, 1);

       Supplier<Instant> instantFn0 = Clock.systemUTC()::instant;
       Fn1<Iterable<Integer>, Iterable<Integer>> tenPerSecond =
           rateLimit(instantFn0, 10L, Duration.ofSeconds(1));
       Fn1<Iterable<Integer>, Iterable<Integer>> oneHundredEveryTwoMinutes =
           rateLimit(instantFn0, 100L, Duration.ofMinutes(2));

       tenPerSecond.fmap(oneHundredEveryTwoMinutes).apply(elements).forEach(System.out::println);

  In the preceding example, the elements will be printed at most 10 elements per second and 100 elements per 120 seconds.

  If the host `Thread` is `interrupted` while the returned `Iterable` is waiting for the next available time slice, an `IterationInterruptedException` will immediately be thrown.

  Note that the returned `Iterable` will never iterate faster than the specified rate limit, but the earliest the next element is available will be dependent on the precision of the underlying instant supplier as well as any overhead involved in producing the element from the original `Iterable`.

- - ### Method Summary

    All Methods Static Methods Instance Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `Iterable<A>` | `checkedApply(Fn0<Instant> instantFn0, Long limit, Duration duration, Iterable<A> as)`
    `static <A> RateLimit<A>` | `rateLimit()`
    `static <A> Fn3<Long,Duration,Iterable<A>,Iterable<A>>` | `rateLimit(Fn0<Instant> instantFn0)`
    `static <A> Fn2<Duration,Iterable<A>,Iterable<A>>` | `rateLimit(Fn0<Instant> instantFn0, Long limit)`
    `static <A> Fn1<Iterable<A>,Iterable<A>>` | `rateLimit(Fn0<Instant> instantFn0, Long limit, Duration duration)`
    `static <A> Iterable<A>` | `rateLimit(Fn0<Instant> instantFn0, Long limit, Duration duration, Iterable<A> as)`

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

    - ### Methods inherited from interface com.jnape.palatable.lambda.functions.Fn4

      `apply, apply, apply, apply, checkedApply, compose, contraMap, diMapL, discardR, flip, fn4, fn4, fn4, fn4, uncurry, widen`

    - ### Methods inherited from interface com.jnape.palatable.lambda.functions.Fn3

      `checkedApply, fn3, fn3, fn3`

    - ### Methods inherited from interface com.jnape.palatable.lambda.functions.Fn2

      `checkedApply, curried, curry, fn2, fromBiFunction, toBiFunction`

    - ### Methods inherited from interface com.jnape.palatable.lambda.functions.Fn1

      `andThen, carry, cartesian, censor, choose, cocartesian, diMap, diMapR, discardL, flatMap, fmap, fn1, fromFunction, lazyZip, listens, local, pure, pureFn1, thunk, toFunction, trampolineM, zip, zip`

    - ### Methods inherited from interface com.jnape.palatable.lambda.monad.Monad

      `join`

    - ### Methods inherited from interface com.jnape.palatable.lambda.functor.Functor

      `coerce`

- - ### Method Detail

    - #### checkedApply

          public Iterable<A> checkedApply(Fn0<Instant> instantFn0,
                                          Long limit,
                                          Duration duration,
                                          Iterable<A> as)

      Specified by:
        `checkedApply` in interface `Fn4<Fn0<Instant>,Long,Duration,Iterable<A>,Iterable<A>>`

    - #### rateLimit

          public static <A> RateLimit<A> rateLimit()

    - #### rateLimit

          public static <A> Fn3<Long,Duration,Iterable<A>,Iterable<A>> rateLimit(Fn0<Instant> instantFn0)

    - #### rateLimit

          public static <A> Fn2<Duration,Iterable<A>,Iterable<A>> rateLimit(Fn0<Instant> instantFn0,
                                                                            Long limit)

    - #### rateLimit

          public static <A> Fn1<Iterable<A>,Iterable<A>> rateLimit(Fn0<Instant> instantFn0,
                                                                   Long limit,
                                                                   Duration duration)

    - #### rateLimit

          public static <A> Iterable<A> rateLimit(Fn0<Instant> instantFn0,
                                                  Long limit,
                                                  Duration duration,
                                                  Iterable<A> as)