Repository navigation
Expose non-owning connections for served-object callbacks - #50
Conversation
Add a test that serves an object holding a clone of its own connection and verifies that dropping the service connection releases both the served object and its requested bus name, guarding against reference cycles between a connection and the objects it serves. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
… tests Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
Served objects need their connection to issue callbacks, but holding a strong handle creates an ownership cycle that keeps the service, transport and well-known name alive. WeakConnection borrows the connection only for the duration of a callback and cannot resurrect it once the last strong owner drops, even while dispatch state still holds an internal reference. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
The callback connection test now stores a downgraded connection so the served object no longer keeps its own connection alive, matching the ownership model documented for callback objects. The connection module README gains a section explaining why served objects should hold weak references and how upgrade behaves across the connection lifetime. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
|
Warning Review limit reached
This review includes 4 billable files and costs up to $1.00. Or wait 14 minutes for your next included review. View limit details
Comment |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Tiny Sweeper reviewTiny Sweeper completed its review; deterministic results follow. State: Incomplete Review snapshot
Completeness: Incomplete What changed`WeakConnection` is introduced in `crates/tinybus/src/connection.rs` as a cloneable struct holding a `std::sync::Weak` to `Inner` and a `std::sync::Weak` to the `CloseOnDrop` lifetime guard, with a `Debug` implementation reporting `has_strong_owner` based on the guard's strong count. `Connection::downgrade()` downgrades both the inner state and the lifetime guard. `WeakConnection::upgrade()` upgrades the `CloseOnDrop` guard first and returns `None` if that fails, then upgrades `Inner`; because the returned `Connection` carries the same guard, a weak reference cannot revive a connection after its last strong owner drops, even while dispatch tasks still hold internal state. An explicitly closed connection that still has an owner remains upgradable, and calls on it return the normal closed-transport errors. The type is re-exported alongside `Connection` from `crates/tinybus/src/lib.rs`, and `docs/modules/connection/README.md` gains a 'Callback ownership' section describing how to store and upgrade the reference for the duration of a callback. Features
TestsNo supported feature-to-test mapping was produced. Test execution is not inferred.
FindingsNo active actionable findings. Could not review: crates/tinybus/src/connection.rs, crates/tinybus/src/connection_tests.rs, crates/tinybus/src/lib.rs, tinysweeper/tests Before merge
How this fits togetherflowchart LR
n0["...on_but_preserves_an_already_admitted_call<br/>changed"]:::changed
n1["clone"]:::impacted
n2["serve_at"]:::impacted
n3["call"]:::impacted
n4["path"]:::impacted
n5["...an_register_an_interface_without_deadlock"]:::impacted
n6["call_raw"]:::impacted
n0 -->|calls| n1
n0 -->|tests| n1
n0 -->|calls| n2
n0 -->|tests| n2
n0 -->|calls| n3
n0 -->|tests| n3
n0 -->|calls| n4
n0 -->|tests| n4
n0 -->|calls| n6
n0 -->|tests| n6
n3 -->|calls| n2
n3 -->|calls| n4
n5 -->|calls| n1
n5 -->|tests| n1
n5 -->|calls| n2
n5 -->|tests| n2
n5 -->|calls| n3
n5 -->|tests| n3
n5 -->|calls| n4
n5 -->|tests| n4
n5 -->|calls| n6
n5 -->|tests| n6
classDef changed fill:#0d4429,stroke:#238636,color:#e6edf3
classDef impacted fill:#161b22,stroke:#6e7681,color:#c9d1d9
classDef flagged fill:#5a1e02,stroke:#d93f0b,color:#ffffff
classDef blocking fill:#67060c,stroke:#f85149,color:#ffffff
Agent review detailscritique
security
tests
commits
description
Evidence and run details
|
There was a problem hiding this comment.
tinysweeper found nothing blocking, but could not review everything, so this is not an approval: crates/tinybus/src/connection.rs, crates/tinybus/src/connection_tests.rs, crates/tinybus/src/lib.rs, tinysweeper/tests.
$0.0054 · 196,236 in / 48,139 out · 32,256 cached (16%) · ladder/vectors-oai3, deepseek-v4.1-flash · 336 embedded
critique: $0.0004 · 35,263 in / 6,622 out · 4,224 cached (12%) · deepseek-v4.1-flash
security: $0.0036 · 110,998 in / 30,604 out · 23,552 cached (21%) · deepseek-v4.1-flash
tests: $0.0009 · 15,700 in / 5,368 out · 0 cached (0%) · deepseek-v4.1-flash
description: $0.0002 · 30,326 in / 2,844 out · 4,480 cached (15%) · deepseek-v4.1-flash
A served object that stores its own
Connectioncreates a cycle: the connection owns the object tree, and the object keeps the connection alive. Dropping the caller’s last handle therefore leaves the object and its bus name alive. Live module callback adapters need non-owning access to avoid this cycle.Add
Connection::downgrade()andWeakConnection::upgrade(). Upgrading first acquires the public lifetime guard, so background dispatch state cannot resurrect a connection after its last owning handle disappears. Existing calls, admission, transport close, ABI and wire behavior remain unchanged. Document callback ownership beside the connection API.Validation:
This is an independent TinyBus prerequisite for the TinyVoice live module migration tracked by tinyhumansai/openhuman#7414. No OpenHuman adapter or release pin is changed here.