Skip to content

Release v1.1.0

Latest

Choose a tag to compare

@github-actions github-actions released this 19 May 01:52
· 56 commits to main since this release
f8b3b3e

This release resolves a full code audit of v1.0.2 — concurrency, lifecycle,
packaging, and API-boundary issues — and removes a class of intermittent CI
failures caused by un-awaited coroutines in the test suite.

Added

  • Public API: ScheduleResult and QueuedRequest are now exported from
    the top-level adaptive_rate_limiter package and from
    adaptive_rate_limiter.scheduler. They are the return type of
    submit_request in INTELLIGENT and ACCOUNT modes.
  • Config: RateLimiterConfig gained max_retries, batch_size,
    stale_entry_ttl, and max_tracking_entries fields, each validated in
    __post_init__.
  • CI: a packaging job builds the wheel and verifies all six bundled Lua
    scripts ship with it, guarding against a regression that would break the
    [redis] install.

Changed

  • ACCOUNT mode: the concurrency limit is now read from the correct
    config field, max_concurrent_executions. Previously the strategy looked
    up a non-existent max_concurrent_requests attribute and silently fell
    back to the hardcoded default of 10.
  • Reservations & streaming: staleness and abandonment detection now use
    a monotonic clock (time.monotonic()), making it immune to wall-clock and
    NTP adjustments. The effective stale-reservation age is derived from
    request_timeout, so cleanup can no longer reclaim a still-running
    reservation.
  • Removed the empty, unused _internal/ package. _-prefixed names were
    never part of the public API, so this is not a breaking change.

Fixed

  • Scheduler loop: the INTELLIGENT mode loop no longer terminates
    permanently when an unexpected exception is raised inside it.
  • Queue race: request enqueue and the _queue_has_items flag are now
    mutated under the per-queue lock, preventing a lost update that could
    leave a non-empty queue unscheduled.
  • Reset watcher: no longer raises RuntimeError: Set changed size during iteration when a watcher fires during reset-time calculation.
  • Shutdown: stop() now cancels and awaits in-flight execution tasks
    (INTELLIGENT and ACCOUNT modes) before the backend shuts down, so
    capacity-release cleanup completes and request coroutines are not left
    un-awaited.
  • Cancellation orphan: a reservation orphaned by cancellation between
    capacity reservation and executor hand-off is now released immediately
    instead of being held until stale cleanup.
  • MemoryBackend: streaming token refunds are reconciled against header
    syncs via a per-key state version, preventing capacity over-admission when
    a server header update superseded a reservation.
  • Streaming: on a successful wrap, reservation ownership is handed to the
    iterator so stale-reservation cleanup cannot reclaim a live stream.

What's Changed

  • fix: resolve confirmed audit issues (concurrency, lifecycle, packaging, API boundary) by @sethbang in #4
  • fix: eliminate un-awaited AsyncMock coroutine leaks (CI flake) by @sethbang in #5
  • ci: bump codecov/codecov-action from 5 to 6 in the actions group across 1 directory by @dependabot[bot] in #1
  • deps: update nox requirement from <2026.0.0,>=2025.11.12 to >=2025.11.12,<2027.0.0 by @dependabot[bot] in #2
  • deps: update mypy requirement from <2.0.0,>=1.19.1 to >=1.19.1,<3.0.0 by @dependabot[bot] in #3
  • chore: add main-branch protection ruleset by @sethbang in #6
  • chore: release 1.1.0 by @sethbang in #7

New Contributors

Full Changelog: v1.0.2...v1.1.0