@@ -132,7 +132,7 @@ class Exporter(AsyncContextManagerMixin, Metadata):
132132 AFTER_LEASE_HOOK, BEFORE_LEASE_HOOK_FAILED, AFTER_LEASE_HOOK_FAILED.
133133 """
134134
135- _lease_scope : LeaseContext | None = field (init = False , default = None )
135+ _lease_context : LeaseContext | None = field (init = False , default = None )
136136 """Encapsulates all resources associated with the current lease.
137137
138138 Contains the session, socket path, and synchronization event needed
@@ -266,9 +266,10 @@ async def _report_status(self, status: ExporterStatus, message: str = ""):
266266 """Report the exporter status with the controller and session."""
267267 self ._exporter_status = status
268268
269- # Update session status if available
270- if self ._lease_scope and self ._lease_scope .session :
271- self ._lease_scope .session .update_status (status , message )
269+ # Update status in lease context (handles session update internally)
270+ # This ensures status is stored even before session is created
271+ if self ._lease_context :
272+ self ._lease_context .update_status (status , message )
272273
273274 try :
274275 controller = await self ._get_controller_stub ()
@@ -409,6 +410,10 @@ async def handle_lease(self, lease_name: str, tg: TaskGroup, lease_scope: LeaseC
409410 # Populate the lease scope with session and socket path
410411 lease_scope .session = session
411412 lease_scope .socket_path = path
413+ # Sync current status to the newly created session
414+ # This ensures the session has the correct status even if _report_status
415+ # was called before the session was created (race condition fix)
416+ session .update_status (lease_scope .current_status , lease_scope .status_message )
412417
413418 # Wait for before-lease hook to complete before processing client connections
414419 logger .info ("Waiting for before-lease hook to complete before accepting connections" )
@@ -449,23 +454,23 @@ async def serve(self): # noqa: C901
449454 async for status in status_rx :
450455 # Check if lease name changed (and there was a previous active lease)
451456 lease_changed = (
452- self ._lease_scope
453- and self ._lease_scope .is_active ()
454- and self ._lease_scope .lease_name != status .lease_name
457+ self ._lease_context
458+ and self ._lease_context .is_active ()
459+ and self ._lease_context .lease_name != status .lease_name
455460 )
456461 if lease_changed :
457462 # After-lease hook for the previous lease (lease name changed)
458- if self .hook_executor and self ._lease_scope .has_client ():
463+ if self .hook_executor and self ._lease_context .has_client ():
459464 with CancelScope (shield = True ):
460465 await self .hook_executor .run_after_lease_hook (
461- self ._lease_scope ,
466+ self ._lease_context ,
462467 self ._report_status ,
463468 self .stop ,
464469 )
465470
466471 logger .info ("Lease status changed, killing existing connections" )
467472 # Clear lease scope for next lease
468- self ._lease_scope = None
473+ self ._lease_context = None
469474 self .stop ()
470475 break
471476
@@ -482,43 +487,48 @@ async def serve(self): # noqa: C901
482487 lease_name = status .lease_name ,
483488 before_lease_hook = Event (),
484489 )
485- self ._lease_scope = lease_scope
490+ self ._lease_context = lease_scope
486491 tg .start_soon (self .handle_lease , status .lease_name , tg , lease_scope )
487492
488493 if current_leased :
489494 logger .info ("Currently leased by %s under %s" , status .client_name , status .lease_name )
490- if self ._lease_scope :
491- self ._lease_scope .update_client (status .client_name )
495+ if self ._lease_context :
496+ self ._lease_context .update_client (status .client_name )
492497
493498 # Before-lease hook when transitioning from unleased to leased
494499 if not previous_leased :
495- if self .hook_executor and self ._lease_scope :
500+ if self .hook_executor and self ._lease_context :
496501 tg .start_soon (
497502 self .hook_executor .run_before_lease_hook ,
498- self ._lease_scope ,
503+ self ._lease_context ,
499504 self ._report_status ,
500505 self .stop , # Pass shutdown callback
501506 )
502507 else :
503508 # No hook configured, set event immediately
504509 await self ._report_status (ExporterStatus .LEASE_READY , "Ready for commands" )
505- if self ._lease_scope :
506- self ._lease_scope .before_lease_hook .set ()
510+ if self ._lease_context :
511+ self ._lease_context .before_lease_hook .set ()
507512 else :
508513 logger .info ("Currently not leased" )
509514
510515 # After-lease hook when transitioning from leased to unleased
511- if previous_leased and self .hook_executor and self ._lease_scope and self ._lease_scope .has_client ():
516+ if (
517+ previous_leased
518+ and self .hook_executor
519+ and self ._lease_context
520+ and self ._lease_context .has_client ()
521+ ):
512522 # Shield the after-lease hook from cancellation
513523 with CancelScope (shield = True ):
514524 await self .hook_executor .run_after_lease_hook (
515- self ._lease_scope ,
525+ self ._lease_context ,
516526 self ._report_status ,
517527 self .stop ,
518528 )
519529
520530 # Clear lease scope for next lease
521- self ._lease_scope = None
531+ self ._lease_context = None
522532
523533 if self ._stop_requested :
524534 self .stop (should_unregister = True )
0 commit comments