Implement JEP-0012: explicit lease lifecycle FSM for exporter#618
Implement JEP-0012: explicit lease lifecycle FSM for exporter#618
Conversation
Replace the ad-hoc event-based coordination (before_lease_hook, after_lease_hook_started/done, lease_ended) with a proper finite state machine (LeaseLifecycle) that owns all phase transitions. Key changes: - New lease_lifecycle.py with LeasePhase enum, transition table, and LeaseLifecycle controller (wait points, end-request tracking) - LeaseContext now holds a LeaseLifecycle instead of raw anyio.Events; drivers_ready/wait_for_drivers delegate to lifecycle - Exporter drives transitions: CREATED → STARTING → BEFORE_LEASE → READY → ENDING → AFTER_LEASE → RELEASING → DONE - _run_before_hook_lifecycle wraps hook execution with transitions - _run_ending_phase shared by _cleanup_after_lease and _handle_end_session (FSM acts as mutex - first to transition wins) - hooks.py no longer sets before_lease_hook; exporter owns all lifecycle transitions - Comprehensive tests for FSM, lifecycle integration, and exporter state machine edge cases Ref: JEP-0012 Made-with: Cursor
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 21 minutes and 55 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (8)
✨ Finishing Touches🧪 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 |
|
Just wanted to see how this looked, and can be done much better than this :D |
Summary
Implements JEP-0012 — replaces the ad-hoc event-based lease coordination (
before_lease_hook,after_lease_hook_started/done,lease_ended) with an explicit finite state machine (LeaseLifecycle).What changed
New
lease_lifecycle.py:LeasePhaseenum with 9 states (CREATED→STARTING→BEFORE_LEASE→READY→ENDING→AFTER_LEASE→RELEASING→DONE/FAILED), transition validation, wait points (wait_ready,wait_complete,wait_end_requested), and end-request tracking.LeaseContextnow holds aLeaseLifecycleinstead of 5 rawanyio.Eventobjects.drivers_ready()/wait_for_drivers()delegate to the lifecycle.skip_after_lease_hookis a property backed by the lifecycle.exporter.pydrives all transitions:_run_before_hook_lifecycle()wraps hook execution withBEFORE_LEASE → READY(or→ ENDINGif end was requested during hook)_run_ending_phase()is shared by_cleanup_after_leaseand_handle_end_session— the FSM transition acts as a mutex (first caller to transition toAFTER_LEASEwins, second waits for completion)_cleanup_after_lease()waits for lifecycle to reachREADY(with safety timeout), then runs the ending phaseserve()/serve_standalone_tcp()uselifecycle.request_end()/lifecycle.wait_complete()instead of raw eventshooks.py: Removedbefore_lease_hook.set()fromrun_before_lease_hook's finally — the exporter now owns all lifecycle transitions.Why
The previous event-based coordination had semantic overloading (
before_lease_hookmeant both "hook finished" and "connections may proceed") that led to deadlocks and race conditions (#567, #569, #598, #614). The FSM makes each state and transition explicit, eliminates the class of bugs where an event is set/checked from the wrong context, and provides a single point of truth for "where is this lease in its lifecycle?"Net code change
-428/+845lines (net-65in production code after removing event gymnastics; the growth is from the FSM module + comprehensive tests)before_lease_hook,after_lease_hook_started,after_lease_hook_done,lease_endedevents fromLeaseContextTest plan
lease_lifecycle_test.pytests pass (29 tests covering transitions, wait points, end-request semantics)exporter_test.pytests pass (16 tests covering cleanup, consecutive leases, safety timeout, idempotent cleanup, lifecycle wrapper)lease_context_test.pytests pass (18 tests for lifecycle-backed LeaseContext)hooks_test.pytests pass (46 tests, updated to removebefore_lease_hookassertions)make pkg-test-jumpstarterpasses (397 tests)make lintpassesMade with Cursor