File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -367,15 +367,30 @@ def _maybe_reap_ttl(self) -> None:
367367 def _schedule_deferred_refill (self , not_before : float ) -> None :
368368 self ._next_refill_at = not_before
369369
370+ def _maybe_reap_stale_spare (self , desired : DriverFingerprint ) -> None :
371+ """Requires ``_lock`` held. Drop ready spare when it no longer matches desired."""
372+ spare = self ._spare
373+ if spare is None or spare .fingerprint == desired :
374+ return
375+ logger .info (
376+ "warm_pool_reap reason=stale_fingerprint fingerprint_hash=%s" ,
377+ spare .fingerprint .fingerprint_hash [:12 ],
378+ )
379+ self ._close_spare_unlocked (spare , reason = "stale_fingerprint" )
380+ self ._spare = None
381+
370382 def _maybe_refill (self ) -> None :
371383 with self ._lock :
372384 if self ._stop .is_set ():
373385 return
374- if self ._spare is not None or self . _building :
386+ if self ._building :
375387 return
376388 desired = self ._desired
377389 if desired is None :
378390 return
391+ self ._maybe_reap_stale_spare (desired )
392+ if self ._spare is not None :
393+ return
379394 if self ._headless_only and not desired .headless :
380395 return
381396 now = self ._clock ()
Original file line number Diff line number Diff line change @@ -153,6 +153,23 @@ def test_take_miss_on_fingerprint_mismatch(self) -> None:
153153 self .assertTrue (pool .live_spare_dirs ())
154154 pool .shutdown ()
155155
156+ def test_stale_spare_reaped_when_desired_fingerprint_changes (self ) -> None :
157+ pool = self ._pool (idle_ttl_seconds = 0 )
158+ fp_a = _fp (user_agent = "A" )
159+ fp_b = _fp (user_agent = "B" )
160+ pool .notify_scrape_finished (fp_a )
161+ self ._wait_spare (pool )
162+ stale_driver = self .built [0 ]
163+ self .spare_ready .clear ()
164+
165+ pool .notify_scrape_finished (fp_b )
166+ self ._wait_spare (pool )
167+
168+ self .assertTrue (stale_driver .closed )
169+ self .assertEqual (len (self .built ), 2 )
170+ self .assertIsNotNone (pool .take (fp_b ))
171+ pool .shutdown ()
172+
156173 def test_unhealthy_spare_is_reaped_not_handed_out (self ) -> None :
157174 pool = self ._pool (health_check = HealthCheckStub (healthy = False ))
158175 fp = _fp ()
You can’t perform that action at this time.
0 commit comments