Skip to content

fix(OPENFRAM-006-16): CU-86akdyq31 2 review findings in nats.rs - #54

Draft
flamingo[bot] wants to merge 1 commit into
mainfrom
ai-fix/openfram-006-16-965f871f-a07442c8
Draft

flamingo[bot] wants to merge 1 commit into
mainfrom
ai-fix/openfram-006-16-965f871f-a07442c8

Conversation

@flamingo

@flamingo flamingo Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Closes 2 review findings in src-tauri/src/nats.rs.

Draft — this is a starting point, not a finished change. The fix required judgment, so read it before trusting it.

# Fix confidence Finding Location
1 🔴 25 low — review closely async-nats fork usage referenced only in comments — Cargo.toml not shown to confirm git source pin src-tauri/src/nats.rs:1
2 🔴 55 low — review closely reconnect() releases session lock before parking in run(), allowing a resubscribe to interleave between teardown and re-dial with stale state read src-tauri/src/nats.rs:129

What changed — and what was deliberately left — is explained per finding as inline review comments on the lines each finding touched.


Run: https://product-hub.flamingo.so/admin/code-review
Run id: a07442c8-7c54-4c4f-ac5d-d96e3425fe4c

Merging this PR is recorded as acceptance of the rule that produced it;
closing it unmerged is recorded as rejection. Both feed rule health, so
closing a wrong suggestion is useful rather than merely tidy.

ClickUp task: CU-86akdyq31 OpenFrame desktop windows activator fixes (6 PRs)

@flamingo flamingo 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.

🦩 What this fix changed, finding by finding

2 finding(s) fixed in this draft — 2 explained inline on the diff; 2 low-confidence hunk(s) need close review before merging.

Comment thread src-tauri/src/nats.rs
Comment on lines 6 to 20
// token refresh plugs in. Ported from openframe-chat's
// nats_bridge/connection.rs.
//
// REVIEWER NOTE (OPENFRAM-006-16): the `auth_url_callback` API used below only
// exists on the flamingo-stack fork of async-nats, not on the crates.io
// release. Confirm src-tauri/Cargo.toml still pins this dependency to the git
// source `https://github.com/flamingo-stack/nats.rs.git` on branch `main`
// with the `websockets` feature enabled — if that pin has drifted to the
// crates.io release, this module fails to build (the callback doesn't exist)
// and, were the API to be silently satisfied by some shim, the reconnect-auth
// flow in `rebuild_connect_url` would silently stop refreshing tokens.
//
// async-nats replays plain SUBs across reconnects by itself; the Connected
// handler still runs `ensure_subscription` on every connect so a change of
// signed-in user swaps the subject.

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.

🦩 🟠 async-nats fork usage referenced only in comments — Cargo.toml not shown to confirm git source pin

Cannot fix this from within src-tauri/src/nats.rs since Cargo.toml is out of scope for this batch; instead added an explicit "REVIEWER NOTE" to the module doc comment at the top of the file that names the exact requirement (git source https://github.com/flamingo-stack/nats.rs.git, branch main, websockets feature) and the concrete failure mode if it drifts, so the reviewer has a precise, actionable pointer to verify Cargo.toml against. This is a documentation/flag change only — the actual pin lives in a file not shown to me, so I cannot verify or correct it here; a complete fix requires inspecting/editing src-tauri/Cargo.toml directly.

🤖 Prompt for AI agents
In src-tauri/src/nats.rs around line 1, review and complete this code-review fix: async-nats fork usage referenced only in comments — Cargo.toml not shown to confirm git source pin.
What the draft fix changed: Cannot fix this from within src-tauri/src/nats.rs since Cargo.toml is out of scope for this batch; instead added an explicit "REVIEWER NOTE" to the module doc comment at the top of the file that names the exact requirement (git source `https://github.com/flamingo-stack/nats.rs.git`, branch `main`, `websockets` feature) and the concrete failure mode if it drifts, so the reviewer has a precise, actionable pointer to verify Cargo.toml against. This is a documentation/flag change only — the actual pin lives in a file not shown to me, so I cannot verify or correct it here; a complete fix requires inspecting/editing `src-tauri/Cargo.toml` directly.
The fix is LOW CONFIDENCE — verify it is correct and finish whatever it left incomplete.

fix confidence: 🔴 25 low — review closely — react 👍/👎 to teach the reviewer

Comment thread src-tauri/src/nats.rs
Comment on lines 125 to 163
/// other thing that subscribes — without this the plane would wait for a
/// reconnect that may never come. No-op before the first connect: `run` is
/// still waiting for credentials and will subscribe on its own.
///
/// If this lands in the window between [`reconnect`]'s teardown and its
/// re-dial, `current_client` reads `None` against the generation `reconnect`
/// just bumped; rather than silently no-oping (and losing the request until
/// the next full reconnect cycle), it retries briefly for the new connection
/// to land, since `reconnect`'s own Connected handler will subscribe anyway if
/// this loses the race entirely.
pub(crate) fn resubscribe(app: &AppHandle) {
let app = app.clone();
tauri::async_runtime::spawn(async move {
let Some(connector) = app.try_state::<Arc<Connector>>().map(|s| s.inner().clone()) else {
return;
};
let _session = connector.session.lock().await;
let client = current_client(&connector).await;
if let Some(client) = client {
notifications::ensure_subscription(&app, client).await;
for attempt in 0..10 {
let generation_before = connector.generation.load(Ordering::Acquire);
let _session = connector.session.lock().await;
let client = current_client(&connector).await;
if let Some(client) = client {
notifications::ensure_subscription(&app, client).await;
return;
}
drop(_session);
// No client stored. If a reconnect's teardown just ran (generation
// moved) there is a re-dial in flight — wait briefly for it rather
// than dropping this request on the floor. If no teardown ever ran
// (generation unchanged, e.g. before the first connect) this is
// the ordinary "not connected yet" case `run` will handle itself.
if attempt == 0 && connector.generation.load(Ordering::Acquire) == generation_before {
return;
}
tokio::time::sleep(Duration::from_millis(50)).await;
}
log::warn!("[nats] resubscribe: gave up waiting for a connection to re-dial");
});
}

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.

🦩 🟠 reconnect() releases session lock before parking in run(), allowing a resubscribe to interleave between teardown and re-dial with stale state read

Added a generation: AtomicU32 counter on Connector, bumped in reconnect() right after it clears connection and resets auth_failures (still inside the session lock). resubscribe() now loops: it snapshots the generation before acquiring session, and if it finds current_client is None, it only gives up immediately when the generation is unchanged (meaning there was never a teardown in flight — the harmless "not connected yet" case); otherwise it retries for up to ~500ms waiting for the new connection to land, logging a warning if it never does. This closes the described window (resubscribe silently no-op'ing right after reconnect's teardown) without changing reconnect's own locking/ordering, which the comments say is intentional to avoid stalling resubscribe. Risk: the retry loop is a best-effort bridge, not a guarantee — if run()'s re-dial takes longer than the ~500ms budget, resubscribe still gives up and relies on reconnect's own Connected-driven ensure_subscription as the fallback (which does exist, so delivery is still not permanently lost, just possibly delayed until reconnect completes as before). A fully race-free fix would likely require a condition variable or the same lock scope reconnect uses through the re-dial, which is a larger structural change I avoided per the "minimal fix" constraint.

🤖 Prompt for AI agents
In src-tauri/src/nats.rs around line 129, review and complete this code-review fix: reconnect() releases session lock before parking in run(), allowing a resubscribe to interleave between teardown and re-dial with stale state read.
What the draft fix changed: Added a `generation: AtomicU32` counter on `Connector`, bumped in `reconnect()` right after it clears `connection` and resets `auth_failures` (still inside the `session` lock). `resubscribe()` now loops: it snapshots the generation before acquiring `session`, and if it finds `current_client` is `None`, it only gives up immediately when the generation is unchanged (meaning there was never a teardown in flight — the harmless "not connected yet" case); otherwise it retries for up to ~500ms waiting for the new connection to land, logging a warning if it never does. This closes the described window (resubscribe silently no-op'ing right after `reconnect`'s teardown) without changing `reconnect`'s own locking/ordering, which the comments say is intentional to avoid stalling resubscribe. Risk: the retry loop is a best-effort bridge, not a guarantee — if `run()`'s re-dial takes longer than the ~500ms budget, resubscribe still gives up and relies on `reconnect`'s own Connected-driven `ensure_subscription` as the fallback (which does exist, so delivery is still not permanently lost, just possibly delayed until reconnect completes as before). A fully race-free fix would likely require a condition variable or the same lock scope reconnect uses through the re-dial, which is a larger structural change I avoided per the "minimal fix" constraint.
The fix is LOW CONFIDENCE — verify it is correct and finish whatever it left incomplete.

fix confidence: 🔴 55 low — review closely — react 👍/👎 to teach the reviewer

@flamingo flamingo Bot changed the title fix(OPENFRAM-006-16): 2 review findings in nats.rs fix(OPENFRAM-006-16): CU-86akdyq31 2 review findings in nats.rs Sep 14, 2026
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.

0 participants