fix: bound a PDU frame with one deadline - #20
Conversation
The session set a five second timeout on each read call, and read_exact loops over read. Every partial read restarted the clock, so a peer that sent one byte every four seconds held the session open forever and the master never got its responses. The receive step now computes one deadline when the first byte of a frame arrives, and gives each following read only the time that remains. The wait for the first byte stays unbounded, so an idle session does not reconnect on its own. Exhausted time fails the frame before the socket call, because a zero timeout means block forever and the standard library rejects a zero duration. The receive step takes the frame budget as an argument. The run loop passes the existing constant. The tests pass a short budget, which pins the boundary in under a second. This follows the netlink acquisition step, which computes one deadline for a whole inventory and passes the remaining time into each wait. A fake master drips one frame byte every two seconds against the actual binary, then asserts that the session ends near five seconds, names the deadline in its log, and accepts the reconnection. A socket pair test drives the receive step with a 100 ms budget and asserts expiry, success inside the budget, and an unbounded idle wait. Both tests fail against the unfixed code. An adversarial review noted that a final read can return just after the deadline and still complete the frame. The overrun is bounded by one read, because the deadline is fixed and the peer cannot extend it. Rejecting a complete PDU at that boundary would discard a valid request, and the sub-millisecond window cannot be tested without flake. Closes #15
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Advanced Run ID: 📒 Files selected for processing (2)
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review. WalkthroughThe session now gives each started AgentX PDU one deadline. Header and payload reads share that deadline. Unit and end-to-end tests verify timeout and successful completion behavior. ChangesFrame Deadline Enforcement
Priority: ➖ Normal Estimated code review effort: 3 (Moderate) | ~25 minutes Change: Bug fix · Severity of issue fixed: Medium Sequence Diagram(s)sequenceDiagram
participant FakeMaster
participant AgentXSession
participant Supervisor
FakeMaster->>AgentXSession: Send PDU bytes over time
AgentXSession->>AgentXSession: Enforce one frame deadline
AgentXSession-->>Supervisor: Report frame deadline error
Supervisor->>FakeMaster: Attempt reconnect
Merge Risk: ⚪ Minimal · up to Idle sessions continue waiting for their first byte, while started frames use the shared deadline. No actionable merge-blocking risk remains. 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
Full details: Linked Issues checkExplanation The implementation in [ Resolution Keep the test writer open after the partial frame, or send enough delayed bytes to keep the unfixed receiver blocked past the bounded assertion. Then assert deadline-based closure and reconnection with a bounded wait. Retain the existing unit coverage for the short frame budget. ✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
✨ Simplify code
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. I am a rabbit watching bytes arrive, Comment |
The session set a five second timeout on each read call, and read_exact
loops over read. Every partial read restarted the clock, so a peer that
sent one byte every four seconds held the session open forever and the
master never got its responses.
The receive step now computes one deadline when the first byte of a frame
arrives, and gives each following read only the time that remains. The
wait for the first byte stays unbounded, so an idle session does not
reconnect on its own. Exhausted time fails the frame before the socket
call, because a zero timeout means block forever and the standard library
rejects a zero duration.
The receive step takes the frame budget as an argument. The run loop
passes the existing constant. The tests pass a short budget, which pins
the boundary in under a second. This follows the netlink acquisition
step, which computes one deadline for a whole inventory and passes the
remaining time into each wait.
A fake master drips one frame byte every two seconds against the actual
binary, then asserts that the session ends near five seconds, names the
deadline in its log, and accepts the reconnection. A socket pair test
drives the receive step with a 100 ms budget and asserts expiry, success
inside the budget, and an unbounded idle wait. Both tests fail against
the unfixed code.
An adversarial review noted that a final read can return just after the
deadline and still complete the frame. The overrun is bounded by one
read, because the deadline is fixed and the peer cannot extend it.
Rejecting a complete PDU at that boundary would discard a valid request,
and the sub-millisecond window cannot be tested without flake.
Closes #15
Summary by CodeRabbit