juju / python-libjuju

Python library for the Juju API
Apache License 2.0
57 stars 93 forks source link

Juju 2.9 `model.wait_for_idle` execution time linearly grows depending on the number of apps provided. #1055

Open valexby opened 1 month ago

valexby commented 1 month ago

Description

Hi,

I have 2.9.45 Juju controller. I noticed that model.wait_for_idle seems to work synchronously, and the more apps I give it to wait, the more it takes to wait for idle. Tested with libjuju 2.9.45 and 2.9.49, works all the same.

Here some very basic example:

In [6]: model = await controller.get_model("openstack")

In [7]: async def wait_for_idle_apps(model, apps):
   ...:     start = time.time()
   ...:     await model.wait_for_idle(apps=apps, idle_period=10, timeout=3600)
   ...:     return time.time() - start
   ...:

In [10]: await wait_for_idle_apps(model, ["cinder"])
Out[10]: 23.35858416557312

In [11]: await wait_for_idle_apps(model, ["cinder", "neutron-api"])
Out[11]: 46.50336813926697

In [12]: await wait_for_idle_apps(model, ["cinder", "neutron-api", "aodh"])
Out[12]: 69.42010927200317

In [13]: await wait_for_idle_apps(model, ["cinder", "neutron-api", "aodh", "heat"])
Out[13]: 92.13254690170288

Also, just for test I tried to run multiple wait_for_idle in async way and it works much better. Just to confirm that there is nothing for controller side that slows down the call:

In [14]: async def wait_for_idle_apps_smart(model, apps):
    ...:     start = time.time()
    ...:     await asyncio.gather(*[model.wait_for_idle(apps=[app], idle_period=10, timeout=600) for app in apps])
    ...:     return time.time() - start
    ...:

In [17]: await wait_for_idle_apps_smart(model, ["cinder"])
Out[17]: 23.614553689956665

In [18]: await wait_for_idle_apps_smart(model, ["cinder", "neutron-api", "aodh", "heat"])
Out[18]: 23.500936269760132

Urgency

Casually reporting

Python-libjuju version

2.9.49,2.9.45

Juju version

2.9.45

Reproduce / Test

It is expected that execution time would not change linearly depending on the number of apps provided. I expect to see execution time around 25 seconds for every call I made below:

In [6]: model = await controller.get_model("openstack")

In [7]: async def wait_for_idle_apps(model, apps):
   ...:     start = time.time()
   ...:     await model.wait_for_idle(apps=apps, idle_period=10, timeout=3600)
   ...:     return time.time() - start
   ...:

In [10]: await wait_for_idle_apps(model, ["cinder"])
Out[10]: 23.35858416557312

In [11]: await wait_for_idle_apps(model, ["cinder", "neutron-api"])
Out[11]: 46.50336813926697

In [12]: await wait_for_idle_apps(model, ["cinder", "neutron-api", "aodh"])
Out[12]: 69.42010927200317

In [13]: await wait_for_idle_apps(model, ["cinder", "neutron-api", "aodh", "heat"])
Out[13]: 92.13254690170288
github-actions[bot] commented 5 days ago

This issue is marked as incomplete because it has been open 30 days with no activity. Please remove incomplete label or comment or this will be closed in 5 days.