Skip to content

fix(panadapter): TTL sweep on deferred pan-status map (#2228). Principle XI.#3037

Merged
ten9876 merged 1 commit into
mainfrom
aetherclaude/issue-2228
May 24, 2026
Merged

fix(panadapter): TTL sweep on deferred pan-status map (#2228). Principle XI.#3037
ten9876 merged 1 commit into
mainfrom
aetherclaude/issue-2228

Conversation

@aethersdr-agent

Copy link
Copy Markdown
Contributor

Summary

Fixes #2228

What was changed

fix(panadapter): TTL sweep on deferred pan-status map (#2228). Principle XI.

Files modified

  • src/models/RadioModel.cpp
  • src/models/RadioModel.h
 src/models/RadioModel.cpp | 21 ++++++++++++++++++---
 src/models/RadioModel.h   |  7 ++++++-
 2 files changed, 24 insertions(+), 4 deletions(-)

Generated by AetherClaude (automated agent for AetherSDR)


🤖 aethersdr-agent · cost: $13.2543 · model: claude-opus-4-7

…ple XI.

The deferred `m_pendingPanStatuses` queue in `RadioModel` holds
`display pan` status that arrives without a `client_handle` so
ownership can be confirmed later. Existing cleanup paths cover the
common cases (disconnect, `removed`, ownership confirmed, non-owned
with `client_handle`), but a pan that another client owns and that
the radio never re-emits with `client_handle` (and never marks
`removed`) leaks an entry indefinitely.

Pair each map value with a `QDateTime::currentSecsSinceEpoch()`
timestamp captured at insert, and sweep entries older than 30 s
each time we insert. Per maintainer note on the issue: dropping a
stale pending entry is never observably wrong because consumption
only happens on ownership confirm — exactly the missing signal that
would otherwise free the entry. The map is small in practice
(typically <10 entries), so an O(N) sweep-on-insert is cheaper than
a periodic-timer alternative.

Three call sites adjusted for the new pair type: the `Defer` branch
of the pan-status handler (insert + sweep), the consumer in
`ensureOwnedPanadapter` (`pending.second`), and the existing
`.clear()`/`.remove()` paths need no change.

Blast radius: risk_score=0.476, 17 high-risk callers (top:
MainWindow::MainWindow, MainWindow::wirePanadapter,
MainWindow::buildMenuBar) — driven by the RadioModel.h include
fan-out. The field is private and its type change is contained to
three sites inside RadioModel.cpp; no public API, signal, or slot
shape changes, so the high-risk callers are not behaviorally
affected.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

@aethersdr-agent aethersdr-agent Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Targeted fix with a clear rationale in the comment — thanks for the thorough write-up of why the sweep is observably safe.

Verified all five touch points of m_pendingPanStatuses are consistent with the new QPair<qint64, QMap<QString, QString>> value type:

  • clear() / remove(panId) are type-agnostic.
  • take() consumer correctly switched to pending.second.isEmpty() and pending.second — and a default-constructed QPair still yields an empty inner map, so the "no pending" path is preserved.
  • Producer stores qMakePair(now, kvs).

One minor note (not blocking):

Wall-clock vs. monotonic time. QDateTime::currentSecsSinceEpoch() is wall-clock and can jump (NTP step, manual adjustment, suspend/resume). For a 30 s TTL the practical risk is low, but QElapsedTimer or std::chrono::steady_clock would be immune by construction. Worth considering if you touch this again, but not worth a respin on its own.

LGTM otherwise.


🤖 aethersdr-agent · cost: $2.7968 · model: claude-opus-4-7

@ten9876 ten9876 merged commit 20d4f8a into main May 24, 2026
5 checks passed
@ten9876 ten9876 deleted the aetherclaude/issue-2228 branch May 24, 2026 15:11
G6PWY-Chris pushed a commit to G6PWY-Chris/AetherSDR that referenced this pull request Jun 22, 2026
…. Principle XI. (aethersdr#3037)

## Summary

Fixes aethersdr#2228

### What was changed

fix(panadapter): TTL sweep on deferred pan-status map (aethersdr#2228). Principle
XI.

### Files modified

- `src/models/RadioModel.cpp`
- `src/models/RadioModel.h`

```
 src/models/RadioModel.cpp | 21 ++++++++++++++++++---
 src/models/RadioModel.h   |  7 ++++++-
 2 files changed, 24 insertions(+), 4 deletions(-)
```

---
Generated by AetherClaude (automated agent for AetherSDR)

---
<sub>🤖 aethersdr-agent · cost: $13.2543 · model: claude-opus-4-7</sub>

Co-authored-by: aethersdr-agent[bot] <273844287+aethersdr-agent[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
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.

RadioModel: m_pendingPanStatuses can grow unbounded for never-claimed pans

1 participant