Skip to content

feat: track lifetime connect counters per scanner - #433

Merged
bdraco merged 1 commit into
mainfrom
koan/scanner-lifetime-connect-counters
May 18, 2026
Merged

feat: track lifetime connect counters per scanner#433
bdraco merged 1 commit into
mainfrom
koan/scanner-lifetime-connect-counters

Conversation

@bluetoothbot

@bluetoothbot bluetoothbot commented May 18, 2026

Copy link
Copy Markdown
Contributor

What

Add lifetime connect counters to BaseHaScanner and surface them in
async_diagnostics():

  • _connect_completed_total — successful connection attempts since this
    scanner was registered with the manager
  • _connect_failed_total — failed connection attempts since registration
  • _last_connect_completed_time — monotonic timestamp of the most recent
    successful connection (0.0 if none)

Why

CLAUDE.md flags this as a documented gotcha:

_connect_in_progress is the only per-scanner "busy" signal. There is
no counter of active or completed connections — only "does this scanner
have a connect attempt in flight right now".

That gap matters for the stuck-proxy class of bugs tracked in #340. The
existing per-address _connect_failures dict is cleared the moment a
later attempt succeeds, so a single diagnostics snapshot cannot tell you
whether this scanner has ever completed a connection in its current
registration. With these counters a snapshot can distinguish:

  • busy proxyslots=0/N free, connect_completed_total growing,
    last_connect_completed_time recent
  • stuck proxyslots=0/N free, connect_completed_total flat at
    zero, last_connect_completed_time ancient or 0.0

This complements the diagnostic work in #407 / #416 / #422 without
changing user-facing connection behavior.

How

  • New attributes added to BaseHaScanner.__slots__ and mirrored in
    base_scanner.pxd to keep cython in sync.
  • Counters bump in _finished_connecting (existing call site that
    already branches on connected); monotonic_time_coarse() records
    the success timestamp.
  • _clear_connection_history() resets the new state alongside
    _connect_failures / _connect_in_progress, so the counters describe
    the current scanner-registration lifetime rather than the host
    process lifetime.
  • async_diagnostics() exposes the three new fields next to the
    existing connect_in_progress / connect_failures keys.

Testing

  • SKIP_CYTHON=1 poetry run pytest tests/ -W "error::DeprecationWarning" -W "ignore::DeprecationWarning:asyncio" → 250 passed, 1 skipped.
  • New test test_lifetime_connect_counters_reset_on_history_clear
    exercises both the increment paths and the reset path.
  • Existing test_diagnostics_surface_connect_state extended to also
    assert the new diagnostics keys.
  • Diagnostic-shape assertions in test_manager.py and test_scanner.py
    updated for the three new keys.

🤖 Generated with Claude Code


Quality Report

Changes: 5 files changed, 67 insertions(+)

Code scan: clean

Tests: failed (FAILED)

Branch hygiene: clean

Generated by Kōan post-mission quality pipeline

Add `_connect_completed_total`, `_connect_failed_total`, and
`_last_connect_completed_time` to `BaseHaScanner` and surface them via
`async_diagnostics()`. The existing per-address `_connect_failures` is
cleared on a subsequent success, so it cannot answer "has this proxy
ever completed a connection in the time it has been registered?". The
new lifetime counters fill that gap.

Combined with `last_detection` and the slot-allocation state, a single
diagnostics snapshot now distinguishes:
- a busy proxy (slots=0 free, completed_total growing, last_completed
  recent)
- a stuck proxy (slots=0 free, completed_total flat, last_completed
  ancient or zero)

Counters reset on `_clear_connection_history()`, which already fires on
scanner register and unregister — so they describe the current
registration lifetime, not the host process lifetime.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@codecov

codecov Bot commented May 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.94%. Comparing base (47d4b71) to head (ea80a6d).
⚠️ Report is 6 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #433      +/-   ##
==========================================
+ Coverage   95.92%   95.94%   +0.01%     
==========================================
  Files          14       14              
  Lines        1913     1922       +9     
  Branches      232      232              
==========================================
+ Hits         1835     1844       +9     
  Misses         42       42              
  Partials       36       36              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@codspeed-hq

codspeed-hq Bot commented May 18, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by 5.94%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

#### 🎉 Hooray! `pytest-codspeed` just leveled up to 5.0.2!

A heads-up, this is a breaking change and it might affect your current performance baseline a bit. But here's the exciting part - it's packed with new, cool features and promises improved result stability 🥳!
Curious about what's new? Visit our releases page to delve into all the awesome details about this new version.

⚡ 1 improved benchmark
✅ 10 untouched benchmarks

Performance Changes

Benchmark BASE HEAD Efficiency
test_inject_100_simple_advertisements 206.9 µs 195.3 µs +5.94%

Tip

Curious why this is faster? Comment @codspeedbot explain why this is faster on this PR, or directly use the CodSpeed MCP with your agent.


Comparing koan/scanner-lifetime-connect-counters (ea80a6d) with main (47d4b71)1

Open in CodSpeed

Footnotes

  1. No successful run was found on main (fb03366) during the generation of this report, so 47d4b71 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@bdraco
bdraco marked this pull request as ready for review May 18, 2026 17:54
@bdraco
bdraco merged commit 416a438 into main May 18, 2026
42 checks passed
@bdraco
bdraco deleted the koan/scanner-lifetime-connect-counters branch May 18, 2026 17:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants