Skip to content

Commit

Permalink
chore: clarify wait for idle params
Browse files Browse the repository at this point in the history
  • Loading branch information
dimaqq committed Oct 3, 2024
1 parent d73db1d commit ce917ec
Showing 1 changed file with 28 additions and 14 deletions.
42 changes: 28 additions & 14 deletions juju/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -2870,15 +2870,15 @@ async def _get_source_api(self, url):
# - may be used with N apps, N units with a mapping {app_name: unit_count}
async def wait_for_idle(self,
apps: Optional[List[str]] = None,
raise_on_error=True,
raise_on_blocked=False,
wait_for_active=False,
timeout=10 * 60,
idle_period=15,
raise_on_error: bool = True,
raise_on_blocked: bool = False,
wait_for_active: bool = False,
timeout: Optional[float] = 10 * 60,
idle_period: float = 15,
check_freq=0.5,
status=None,
wait_for_at_least_units=None,
wait_for_exact_units: Union[None, int, Dict[str, int]] = None,
status: Optional[str] = None,
wait_for_at_least_units: Optional[int] = None,
wait_for_exact_units: Optional[int] = None,
):
"""Wait for applications in the model to settle into an idle state.
Expand Down Expand Up @@ -2930,8 +2930,6 @@ async def wait_for_idle(self,

_wait_for_units = wait_for_at_least_units if wait_for_at_least_units is not None else 1

timeout = timedelta(seconds=timeout) if timeout is not None else None
idle_period = timedelta(seconds=idle_period)
start_time = datetime.now()
# Type check against the common error of passing a str for apps
if apps is not None and (not isinstance(apps, list) or
Expand All @@ -2946,15 +2944,22 @@ async def wait_for_idle(self,
units_ready: Set[str] = set() # The units that are in the desired state
last_log_time: List[Optional[datetime]] = [None]

# FIXME seems inconsistent wrt. use in integration tests
if wait_for_exact_units is not None:
assert isinstance(wait_for_exact_units, int) and wait_for_exact_units >= 0, \
'Invalid value for wait_for_exact_units : %s' % wait_for_exact_units

while True:
if (await self._wait_for_idle_cycle(
if (await self._check_idle(
apps=apps,
raise_on_error=raise_on_error,
raise_on_blocked=raise_on_blocked,
status=status,
wait_for_at_least_units=wait_for_at_least_units,
wait_for_exact_units=wait_for_exact_units,
timeout=timeout,
idle_period=idle_period,
_wait_for_units=_wait_for_units,
idle_times=idle_times,
units_ready=units_ready,
last_log_time=last_log_time,
Expand All @@ -2964,17 +2969,25 @@ async def wait_for_idle(self,

await jasyncio.sleep(check_freq)

async def _wait_for_idle_cycle(
async def _check_idle(
self,
*,
apps: List[str],
raise_on_error: bool,
raise_on_blocked: bool,
status: Optional[str],
wait_for_at_least_units: Optional[int],
wait_for_exact_units: Optional[int],
timeout: Optional[float],
idle_period: float,
_wait_for_units: int,
idle_times: Dict[str, datetime] = {},
units_ready: Set[str] = set(), # The units that are in the desired state
last_log_time: List[Optional[datetime]] = [None],
start_time: datetime = datetime.now(),
):
_timeout = timedelta(seconds=timeout) if timeout is not None else None
_idle_period = timedelta(seconds=idle_period)
log_interval = timedelta(seconds=30)
# The list 'busy' is what keeps this loop going,
# i.e. it'll stop when busy is empty after all the
Expand Down Expand Up @@ -3028,6 +3041,7 @@ async def _wait_for_idle_cycle(
(len(app.units), _wait_for_units))
return False
# User is waiting for at least a certain # of units, and we have enough
# FIXME seems to skip unit status checks, is that expected?
elif wait_for_at_least_units and len(units_ready) >= _wait_for_units:
# So no need to keep looking, we have the desired number of units ready to go,
# exit the loop. Don't just return here, though, we might still have some
Expand Down Expand Up @@ -3085,7 +3099,7 @@ async def _wait_for_idle_cycle(
# FIXME key in units dict
idle_start = idle_times.setdefault(unit.name, now)

if now - idle_start < idle_period:
if now - idle_start < _idle_period:
busy.append("{} [{}] {}: {}".format(unit.name,
unit.agent_status,
unit.workload_status,
Expand All @@ -3104,7 +3118,7 @@ async def _wait_for_idle_cycle(
if not busy:
return True

if timeout is not None and datetime.now() - start_time > timeout:
if _timeout is not None and datetime.now() - start_time > _timeout:
raise jasyncio.TimeoutError("\n ".join(["Timed out waiting for model:", *busy]))

if last_log_time[0] is None or datetime.now() - last_log_time[0] > log_interval:
Expand Down

0 comments on commit ce917ec

Please sign in to comment.