refactor: narrow async lock scopes (#18418)

## Why

This is part of the follow-up work from #18178 to make Codex ready for
Clippy's
[`await_holding_lock`](https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_lock)
/
[`await_holding_invalid_type`](https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_invalid_type)
lints.

This bottom PR keeps the scope intentionally small:
`NetworkProxyState::record_blocked()` only needs the state write lock
while it mutates the blocked-request ring buffer and counters. The debug
log payload and `BlockedRequestObserver` callback can be produced after
that lock is released.

## What changed

- Copies the blocked-request snapshot values needed for logging while
updating the state.
- Releases the `RwLockWriteGuard` before logging or notifying the
observer.

## Verification

- `cargo test -p codex-network-proxy`


---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/18418).
* #18698
* #18423
* __->__ #18418
This commit is contained in:
Michael Bolin
2026-04-20 19:23:30 -07:00
committed by GitHub
Unverified
parent d6af7a6c03
commit ff05532723
+14 -17
View File
@@ -420,32 +420,29 @@ impl NetworkProxyState {
let blocked_for_observer = entry.clone();
let blocked_request_observer = self.blocked_request_observer.read().await.clone();
let violation_line = blocked_request_violation_log_line(&entry);
let mut guard = self.state.write().await;
let host = entry.host.clone();
let reason = entry.reason.clone();
let decision = entry.decision.clone();
let source = entry.source.clone();
let protocol = entry.protocol.clone();
let port = entry.port;
guard.blocked.push_back(entry);
guard.blocked_total = guard.blocked_total.saturating_add(1);
let total = guard.blocked_total;
while guard.blocked.len() > MAX_BLOCKED_EVENTS {
guard.blocked.pop_front();
}
let (total, buffered) = {
let mut guard = self.state.write().await;
guard.blocked.push_back(entry);
guard.blocked_total = guard.blocked_total.saturating_add(1);
let total = guard.blocked_total;
while guard.blocked.len() > MAX_BLOCKED_EVENTS {
guard.blocked.pop_front();
}
(total, guard.blocked.len())
};
debug!(
"recorded blocked request telemetry (total={}, host={}, reason={}, decision={:?}, source={:?}, protocol={}, port={:?}, buffered={})",
total,
host,
reason,
decision,
source,
protocol,
port,
guard.blocked.len()
"recorded blocked request telemetry (\
total={total}, host={host}, reason={reason}, \
decision={decision:?}, source={source:?}, \
protocol={protocol}, port={port:?}, buffered={buffered})"
);
debug!("{violation_line}");
drop(guard);
if let Some(observer) = blocked_request_observer {
observer.on_blocked_request(blocked_for_observer).await;