Skip to content

fix(ci): satisfy clippy unwrap_or_default on rtmp_bridge ConnState#34

Merged
AlexanderWagnerDev merged 7 commits into
mainfrom
cursor/ci-autofix-automation-a40f
Jul 2, 2026
Merged

fix(ci): satisfy clippy unwrap_or_default on rtmp_bridge ConnState#34
AlexanderWagnerDev merged 7 commits into
mainfrom
cursor/ci-autofix-automation-a40f

Conversation

@cursor

@cursor cursor Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes CI failure on PR #33 (cargo clippy -- -D warnings) by replacing or_insert_with(ConnState::default) with or_default() in on_connect().

Includes the rtmp_bridge ConnState preservation fix from #33 plus this clippy lint fix so Tests workflow passes.

Test plan

  • CI cargo clippy --all-targets -- -D warnings should pass
  • Existing Tests workflow (fmt, clippy, build, test) should pass
Open in Web View Automation 

Summary by CodeRabbit

  • Bug Fixes
    • Fixed ghost “active” session rows when switching publisher/player streams on the same connection.
    • Improved per-connection state handling to preserve connect-time authorization and correctly deactivate prior sessions during stream replacement.
    • Added safe rollback when a publisher/player stream switch fails, keeping stream tracking accurate.
    • Reworked publisher/player stats reset and delta calculations to keep byte/rate totals consistent after stream changes.
  • Documentation
    • Updated scan tracking notes with the latest target and findings.
  • Tests
    • Added coverage for connect state preservation, stream switching rollback, and correct stats reset consumption.

cursoragent and others added 2 commits July 2, 2026 03:04
…eam switch

on_connect() used HashMap::insert which wiped publisher/player state when
authorize_publish() already ran during the same poll() tick (fast handshake +
publish). That rejected legitimate publishers and left ghost active publisher
rows blocking re-publish.

Also deactivate prior publisher/player DB rows when the same connection
switches streams via a second publish/play on the same TCP session.

Co-authored-by: Alexander Wagner <info@alexanderwagnerdev.com>
Replace or_insert_with(ConnState::default) with or_default() in
on_connect() so cargo clippy -- -D warnings passes on the rtmp_bridge
ConnState preservation change.

Co-authored-by: Alexander Wagner <info@alexanderwagnerdev.com>
@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: e1e7cbb6-3f1c-4f86-878d-fae1402657de

📥 Commits

Reviewing files that changed from the base of the PR and between 72d374b and 4ccc879.

📒 Files selected for processing (1)
  • src/rtmp_bridge.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/rtmp_bridge.rs

📝 Walkthrough

Walkthrough

DbRtmpBridge now preserves per-connection state in on_connect, resets publisher/player stats after stream replacement, handles stream switches by deactivating prior rows and rolling back on failure, and updates the bug-scan progress note for the rtmp_bridge pass.

Changes

RTMP bridge session state fix

Layer / File(s) Summary
Preserve ConnState and reset stats
src/rtmp_bridge.rs
ConnState now tracks session byte rebasing and pending stats resets, publisher/player stats use session deltas with reset paths, and on_connect preserves existing per-connection state.
Deactivate prior publisher on stream switch
src/rtmp_bridge.rs
authorize_publish deactivates the previous publisher row before switching streams, restores it on failure, and schedules a stats reset.
Deactivate prior player on stream switch
src/rtmp_bridge.rs
on_play replaces the tracked player session, deactivates the previous row, restores prior state on failure, and schedules a stats reset.
Bug-scan progress notes update
.cursor/bug-scan-progress.md
The scan date, module checklist, and findings section were updated for the rtmp_bridge pass.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

  • OpenRTMP/librtmp2-server#26: This also changes src/rtmp_bridge.rs connection and stream-switch state handling, especially player-side state updates.
  • OpenRTMP/librtmp2-server#31: Both PRs touch the RTMP publish/play flow and related lifecycle handling in the same server.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the clippy-related ConnState change, though it understates the broader rtmp_bridge lifecycle fixes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cursor/ci-autofix-automation-a40f

Comment @coderabbitai help to get the list of available commands.

@AlexanderWagnerDev AlexanderWagnerDev marked this pull request as ready for review July 2, 2026 12:38
Copilot AI review requested due to automatic review settings July 2, 2026 12:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the RTMP↔DB integration (DbRtmpBridge) to preserve per-connection state across connection lifecycle callbacks (fixing a clippy-triggering pattern) and to prevent “ghost” active publisher/player rows when a single TCP connection switches streams.

Changes:

  • Replace HashMap::insert(conn, ConnState::default()) with entry(conn).or_default() in on_connect() to avoid wiping an already-initialized ConnState.
  • On stream switches, deactivate any prior publisher/player DB row associated with the same connection before establishing the new session.
  • Add unit tests covering ConnState preservation and publisher/player deactivation on stream switches; update bug-scan progress notes.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
src/rtmp_bridge.rs Preserves existing ConnState on connect, deactivates prior publisher/player rows on stream switch, and adds targeted unit tests.
.cursor/bug-scan-progress.md Marks rtmp_bridge scan complete and records the fixed findings.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/rtmp_bridge.rs Outdated
Comment on lines +273 to +275
// Use or_insert so a publish/play callback that already ran during the same
// poll() tick (before this hook) keeps its ConnState — insert() would wipe
// an authorized publisher/player and leave a ghost active row in the DB.
Comment thread src/rtmp_bridge.rs Outdated
Comment on lines +299 to +303
// A connection may issue publish more than once (stream switch). Release any
// prior publisher row so we do not leave active=true ghosts in the DB.
{
let mut guard = self.conns.lock().unwrap();
if let Some(mut old_pub) = guard.get_mut(&conn).and_then(|cs| cs.publisher.take()) {
Comment thread src/rtmp_bridge.rs Outdated
Comment on lines +369 to +373
// Same connection may play a different stream; deactivate the prior row.
{
let mut guard = self.conns.lock().unwrap();
if let Some(mut old_player) = guard.get_mut(&conn).and_then(|cs| cs.player.take()) {
old_player.active = false;

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/rtmp_bridge.rs`:
- Around line 369-380: The stream-switch path in `RtmpBridge` leaves the
connection’s in-memory `stream_id` stale after taking the old `player`, which
breaks later player-only state updates for the new stream. Update the connection
state in the same switch flow that handles `cs.player.take()` so `cs.stream_id`
is refreshed to the current stream before any deletion-signalling logic runs.
Also adjust the related player-only handling in the matching `RtmpBridge`
update/deletion paths so they rely on the refreshed `stream_id` state rather
than the old one.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 3dae8011-3145-4a1d-9449-ed32a779f8b9

📥 Commits

Reviewing files that changed from the base of the PR and between bd7dd2b and 576d643.

📒 Files selected for processing (2)
  • .cursor/bug-scan-progress.md
  • src/rtmp_bridge.rs

Comment thread src/rtmp_bridge.rs Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 576d6435c0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/rtmp_bridge.rs Outdated
// prior publisher row so we do not leave active=true ghosts in the DB.
{
let mut guard = self.conns.lock().unwrap();
if let Some(mut old_pub) = guard.get_mut(&conn).and_then(|cs| cs.publisher.take()) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve the current publisher until replacement succeeds

When an already-publishing connection sends another publish that is rejected, for example because publisher_try_acquire later finds the target stream already has an active publisher, this take() has already removed and deactivated the connection's current publisher row. The function then returns Err with cs.publisher empty, so subsequent stats/close handling cannot represent the publisher that was active before the failed replacement; defer deactivating the old row until after the new slot is acquired or restore it on failure.

Useful? React with 👍 / 👎.

Comment thread src/rtmp_bridge.rs Outdated
Comment on lines +369 to +372
// Same connection may play a different stream; deactivate the prior row.
{
let mut guard = self.conns.lock().unwrap();
if let Some(mut old_player) = guard.get_mut(&conn).and_then(|cs| cs.player.take()) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Update the tracked stream when replacing a player

When this newly-supported player stream switch succeeds on a player-only connection, the old player is deactivated but cs.stream_id is left pointing at the first stream because the later assignment only runs when it is empty. Callers such as the server poll loop use stream_id_for_conn() after on_play() to set relay/deletion tracking, so switching from stream A to B can keep routing/tracking the connection as A; update the stored stream id for the replacement player while preserving any publisher-owned stream id if that mixed role is intentional.

Useful? React with 👍 / 👎.

Comment thread src/rtmp_bridge.rs Outdated
}

// A connection may issue publish more than once (stream switch). Release any
// prior publisher row so we do not leave active=true ghosts in the DB.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Refresh relay state after a replacement publish

When this new same-connection publish switch succeeds, only DbRtmpBridge state is updated. In the inspected production path in src/server.rs, conn.relay_key and the tracked deletion stream are copied from stream_id_for_conn() only inside if stream.is_publishing && !entry.publishing, so an already-publishing connection keeps relaying/tracking the previous stream while the DB now marks the replacement stream active; refresh the poll-loop state after a replacement publish or reject such switches.

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/rtmp_bridge.rs`:
- Around line 341-352: The rollback path in `RTMPBridge` is restoring
`ConnState.publisher` before confirming the database reactivation succeeded.
Update the `if !self.db.publisher_try_acquire(&pub_row)` branch to check the
result of `publisher_update` first, and only set `old_pub.active = true` and
store it back into `self.conns` after the DB write succeeds; if the write fails,
leave the in-memory state unchanged and handle the failure explicitly.
- Around line 428-431: The old-player deactivation in rtmp_bridge.rs is ignoring
the result of player_update, so a failed write can leave both the old and new
player active. Update the old-player branch in the relevant rtmp bridge handler
to check the return value from self.db.player_update for old_player.id, and
handle/report the failure instead of continuing silently. Make sure the fix is
tied to the old_player deactivation path so the row cannot remain active when
the update fails.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: dc5fb180-095a-45f2-bb06-7502dc2dcba5

📥 Commits

Reviewing files that changed from the base of the PR and between 576d643 and 4ef491a.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (1)
  • src/rtmp_bridge.rs

Comment thread src/rtmp_bridge.rs
Comment thread src/rtmp_bridge.rs Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4290720fed

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/rtmp_bridge.rs
Comment on lines +316 to +319
let old_pub = {
let mut guard = self.conns.lock().unwrap();
guard.get_mut(&conn).and_then(|cs| cs.publisher.take())
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reset stats when replacing the publisher

When this branch handles an already-publishing connection, it removes the old publisher but leaves the connection-level last_stats_at and bytes_at_last_stats from the previous stream intact. The server later passes connection-lifetime media_bytes_received into update_publisher_stats, so after a successful switch the new publisher row can skip its first update for up to a second and then report bytes/bitrate that include traffic from the old stream. Reset the stats baseline when a replacement publisher is installed.

Useful? React with 👍 / 👎.

Comment thread src/rtmp_bridge.rs
let mut guard = self.conns.lock().unwrap();
let cs = guard.entry(conn).or_default();
let old_player = cs.player.take();
cs.player = Some(player_row);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reset stats when replacing the player

When a playing connection switches to another stream here, the new player row inherits the connection-level last_stats_at and bytes_at_last_stats from the previous player. The poll loop later calls update_player_stats with connection-lifetime media_bytes_sent, so the replacement player can skip its first stats flush and then report bytes/bitrate from the old stream as if they belonged to the new viewer session. Reset the player stats baseline when installing a replacement player.

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/rtmp_bridge.rs`:
- Around line 72-80: The stats reset bookkeeping in RtmpBridge is shared across
publisher and player paths, which can cause one role’s replacement to clear the
other role’s pending reset and rebase the wrong DB row. Update the state in
RtmpBridge to keep separate baselines and reset flags for publisher and player,
or make the pending reset explicitly target a role, and adjust the stat
update/reset handling in the affected publisher/player methods so each path only
consumes its own state. Add a regression test covering a mixed publish+play
connection where one side is replaced and the other continues reporting stats.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6f26cbee-0668-4073-82a5-1c40b2b2b61b

📥 Commits

Reviewing files that changed from the base of the PR and between 4290720 and 72d374b.

📒 Files selected for processing (1)
  • src/rtmp_bridge.rs

Comment thread src/rtmp_bridge.rs Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 72d374b20b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/rtmp_bridge.rs Outdated
Comment on lines +157 to +160
if cs.stats_reset_pending {
cs.stats_reset_pending = false;
cs.bytes_base = media_bytes_received;
cs.bytes_at_last_stats = 0;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Use per-role stats reset state

When a connection is both publishing and playing and only one role is replaced, this shared reset flag/base can be consumed by the other role. In the server poll loop I checked, publisher stats are updated before player stats (src/server.rs lines 316-325), so a player switch sets stats_reset_pending in on_play, but the next update_publisher_stats enters this branch, clears it, and sets bytes_base from media_bytes_received; the replacement player then keeps the old player baseline and reports bytes/bitrate from the previous viewer session. Keep separate publisher/player reset and byte-base state so one role cannot consume the other's reset.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@AlexanderWagnerDev AlexanderWagnerDev merged commit 8eb05d6 into main Jul 2, 2026
4 checks passed
@AlexanderWagnerDev AlexanderWagnerDev deleted the cursor/ci-autofix-automation-a40f branch July 2, 2026 14:15
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.

3 participants