LangExtract.Runner.Limiter (LangExtract v0.7.0)

Copy Markdown View Source

The runner's shared request budget: an RPM token bucket plus an in-flight cap, with global backoff on retry-after.

Chunk tasks call acquire/2 before each HTTP request and release/1 after it completes. Acquirers are monitored — a killed task (stream halt, crash) releases its slot automatically, so budget can never leak. pause/2 holds all admission until a deadline: one 429 informs every in-flight chunk instead of N requests independently colliding with the same exhausted window.

Emits [:lang_extract, :limiter, :wait] whenever an acquire had to wait, with the wait duration, the reason that blocked it first (:rpm | :in_flight | :retry_after), and the limiter pid.

Tokens refill lazily from elapsed time — no timer ticks. The clock is injectable (:clock, a zero-arity fun returning milliseconds) so tests run on virtual time.

Summary

Functions

Blocks until a request slot and a token are granted.

Returns a specification to start this module under a supervisor.

Pauses all admission for ms milliseconds (a retry-after deadline).

Releases the caller's in-flight slot after its request completes.

Types

option()

@type option() ::
  {:rpm, pos_integer() | :infinity}
  | {:max_in_flight, pos_integer()}
  | {:clock, (-> integer())}
  | {:name, GenServer.name()}

Functions

acquire(limiter, timeout \\ :infinity)

@spec acquire(GenServer.server(), timeout()) :: :ok

Blocks until a request slot and a token are granted.

Returns :ok. The caller is monitored until it calls release/1 (or dies, which releases implicitly).

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

pause(limiter, ms)

@spec pause(GenServer.server(), non_neg_integer()) :: :ok

Pauses all admission for ms milliseconds (a retry-after deadline).

Repeated pauses extend to the furthest deadline; they never shorten it.

release(limiter)

@spec release(GenServer.server()) :: :ok

Releases the caller's in-flight slot after its request completes.

start_link(opts)

@spec start_link([option()]) :: GenServer.on_start()