Skip to content

Unified statistics API across fast path and slow path #64

Description

@Llucs

Problem

backon has two retry loops with separate state objects:

  • Fast path (_FastState in _retry/_fast.py): bare-bones __slots__ dataclass with elapsed, outcome, tries. No .statistics property.
  • Slow path (RetryState in _state.py): full dataclass with .statistics property returning start_time, attempt_number, idle_for, elapsed.

This means:

  1. Users in the fast path cannot access retry statistics at all
  2. The statistics dict keys differ from tenacity's convention
  3. There is no public Attempt or RetryState exposed to user code — the to_details() dict is the only interface
  4. idle_for is buggy in the slow path (see state.idle_for += state.elapsed accumulates total time, not idle time — statistic grows quadratically #33 — grows quadratically)

Proposed Solution

  1. Add .statistics to _FastState — return a consistent dict matching the slow path format
  2. Public RetryStatistics dataclass — instead of a raw dict, expose a typed dataclass:
    @dataclass
    class RetryStatistics:
        start_time: float
        attempt_number: int
        idle_for: float
        elapsed: float
        outcome: Attempt | None
  3. Expose on Retrying and RetryingCaller — after a retry completes, users can inspect retrying.statistics for the last call
  4. Fix idle_for (reference state.idle_for += state.elapsed accumulates total time, not idle time — statistic grows quadratically #33) as part of this change

Alternatives

  • Keep the current dict-based to_details() (type-unsafe, inconsistent)
  • Only fix idle_for and leave the rest (incomplete solution)
  • Remove statistics entirely (loss of useful debugging info)

Additional Context

tenacity exposes retrying.statistics as a dict via threading.local(). backon should provide something similar but typed and consistent across all modes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions