fix(session): harden persistent session expiry lifecycle - #2255
Conversation
Refs: MSG-339
Refs: MSG-339
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughThe session pipeline now accepts injected lifecycle dependencies and routes delayed cleanup through a cancellable task. Controller closure, reconnect, and disconnected-session tracking are updated. New tests cover expiry tasks and pipeline lifecycle behavior. ChangesSession pipeline lifecycle
Priority: ➖ Normal Estimated code review effort: 3 (Moderate) | ~25 minutes Change: Bug fix Sequence Diagram(s)sequenceDiagram
participant SessionManagerPipeLine
participant SessionExpiryTask
participant SessionExpiryScheduler
participant PipelineExecutor
participant SessionStateFileStore
SessionManagerPipeLine->>SessionExpiryTask: schedule expiry cleanup
SessionExpiryTask->>SessionExpiryScheduler: schedule timer callback
SessionExpiryScheduler->>SessionExpiryTask: fire timer callback
SessionExpiryTask->>PipelineExecutor: submit cleanup
PipelineExecutor->>SessionManagerPipeLine: run controller cleanup
SessionManagerPipeLine->>SessionStateFileStore: delete state file after successful closure
Merge Risk: 🔵 Low · up to The lifecycle failure is not reachable through the established paths. The remaining test naming requirement can be addressed before merge without affecting session behavior. Security Architecture ReviewSecurity architecture risk: 🟡 Moderate · up to The change protects normal expiry and reconnect ordering, but a failed expiry-cleanup submission can leave a persistent session unable to reconnect. The likelihood of that failure in production and its recovery behavior remain unclear. Retained concerns
Security review detailsSecurity Blast Radius
Security Findings and Attack Paths
Trust Boundaries and Controls
Resilience and Maintainability Implications
Hardening Proposals
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 5.06% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 79 functions across 9 files. (1 skipped: 1 unsupported.) ✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
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. Comment |
Refs: MSG-339
Refs: MSG-339
|
@coderabbitai review |
|
Refs: MSG-339
Refs: MSG-339
|
@coderabbitai review |
✅ Action performedReview finished.
|
Refs: MSG-339
Refs: MSG-339
Refs: MSG-339
Refs: MSG-339
Refs: MSG-339
Refs: MSG-339
Refs: MSG-339
Refs: MSG-339
Refs: MSG-339
Summary
Tracked by MSG-339. This PR hardens persistent-session reconnect/expiry handling and establishes one lifecycle mechanism for active close, disconnected close, reset, expiry,
administrative close, duplicate replacement, and shutdown.
The core rule is now explicit:
SessionManagerPipeLineownsSubscriptionControllerdestruction.SessionImpl.close()releases session-owned resources only.Lifecycle invariants
SessionImplper session ID.persistentControllersrepresents persistent ownership;disconnectedControllersrepresents disconnected state.SubscriptionControllerdestruction passes through one pipeline finalizer.Race handling
Reconnect wins
The reconnect cancels the pending
SessionExpiryTask, restores the same persistent controller, clears disconnected accounting, and stale queued cleanup cannot remove it later.Expiry wins
Expiry finalizes the old controller and persistence first. A later reconnect creates a fresh controller from fresh session state.
Both orderings are deterministic because lifecycle work for a session ID executes through the same pipeline executor.
Regression coverage
SessionManagerPipeLineTestcovers:SessionExpiryTaskTestcovers:SessionImplLifecycleTestlocks the ownership boundary thatSessionImpl.close()must never destroy theSubscriptionController.SessionManagerPipeLineScaleTestadds bounded high-churn regression coverage for 2,048 independent transient sessions, 2,048 concurrent producer lifecycle operations, 1,024 persistent expiries with pending Wills, and 1,000 reconnect/disconnect cycles on one persistent session.MQTTConnectionTestnow verifies that an ungraceful MQTT 3.1/3.1.1 disconnect produces the configured Will message end to end.The focused MQTT session-recovery workflow now triggers for session lifecycle test changes and runs all three lifecycle suites.
Documentation
The lifecycle ownership model, transition matrix, persistence semantics, Will behavior, shutdown behavior, and review checklist are documented in:
docs/session-lifecycle.mdThe source-level invariants in
SessionManagerPipeLinelink directly to that document.Validation
Refs: MSG-339