mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-11 13:17:07 +00:00
perf(constructor): park the bootstrap-section SPOT carrier in compose too
On a compose host no applications carrier sits between the add_host placement and the stage-wide park, so every SPOT-reading task of the pre-flight checks and the package batch rendered the applications SPOT cold. In the galaxyserver production deploy of2fd6c6d(compose) the seven tasks from "Fail when a docker network does not belong to its entity" to "Install the packages of every role this host may run" took 10.3 to 12.3 s each, 77.4 s together, while the explicit SPOT renders of the same run took 9.2 to 9.8 s; echoserver2fd6c6dand galaxyserver9e1cf40show the same pattern.778c18fb23parked this carrier only in swarm because "in compose the section runs in about a second". The pre-flight checks (a67dd9b372) and the package batch (18ea75049e) came later and changed that. Swarm already runs this section under the carrier, and the key still rejects a carrier whose roles tree or stable variable signature changed, so compose now parks it as swarm does. Projected from the log: about 60 s less per compose deploy (seven cold renders become one), not yet re-measured on a deploy. | 🎯 Fix | 💥 Break | 🌱 Efficiency | ⚡ Speed | 🛡️ Security | 🏆 Score | Gate | | --- | --- | --- | --- | --- | --- | --- | | 88 % | 5 % | – | – | ~100 % | 84 | ⛔ fix 88 % < 90 | Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
025ebe9754
commit
458c4db1b6
3 files changed
+75
-3
No files matched your search
@@ -14,8 +14,8 @@ the token store digest and ``inventory_hostname``::
|
||||
|
||||
``tasks/stages/01_constructor.yml`` parks three of them: a block-scoped one
|
||||
for the merge block, which it drops again at the block's end, one after the
|
||||
``add_host`` tasks for the swarm bootstrap roles, parked only when
|
||||
``DEPLOYMENT_MODE`` is ``swarm``, and the stage-wide one after the token store. ``merged_applications_cache_key`` reads ``group_names``, so a
|
||||
``add_host`` tasks for the pre-flight checks, the package batch and the
|
||||
bootstrap roles, and the stage-wide one after the token store. ``merged_applications_cache_key`` reads ``group_names``, so a
|
||||
carrier whose groups no longer match is rejected and the reader renders
|
||||
afresh. ``merged_users_cache_key`` adds a digest of the tokens the users are
|
||||
hydrated from (the tokens file, or the ``sys_token_store_users`` fact once the
|
||||
|
||||
@@ -68,7 +68,6 @@
|
||||
|
||||
- name: 🧊 Render the applications SPOT once for the bootstrap section
|
||||
applications_carrier: {}
|
||||
when: IS_SWARM_MODE
|
||||
|
||||
- name: "🛫 Pre-flight checks"
|
||||
ansible.builtin.include_tasks: ./tasks/utils/constructor/preflight.yml
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
import unittest
|
||||
|
||||
from utils.cache.yaml import load_yaml_any
|
||||
|
||||
from . import PROJECT_ROOT
|
||||
|
||||
CONSTRUCTOR = PROJECT_ROOT / "tasks" / "stages" / "01_constructor.yml"
|
||||
PLACEMENT = "./tasks/utils/constructor/placement.yml"
|
||||
PREFLIGHT = "🛫 Pre-flight checks"
|
||||
|
||||
|
||||
def _carrier(task: dict) -> dict | None:
|
||||
args = task.get("applications_carrier")
|
||||
return args if isinstance(args, dict) else None
|
||||
|
||||
|
||||
def _parks(task: dict) -> bool:
|
||||
args = _carrier(task)
|
||||
return args is not None and not args.get("clear", False)
|
||||
|
||||
|
||||
def _clears(task: dict) -> bool:
|
||||
args = _carrier(task)
|
||||
return args is not None and bool(args.get("clear", False))
|
||||
|
||||
|
||||
class TestConstructorBootstrapCarrier(unittest.TestCase):
|
||||
def setUp(self) -> None:
|
||||
self.tasks = load_yaml_any(str(CONSTRUCTOR))
|
||||
self.placement = next(
|
||||
index
|
||||
for index, task in enumerate(self.tasks)
|
||||
if task.get("ansible.builtin.include_tasks") == PLACEMENT
|
||||
)
|
||||
self.preflight = next(
|
||||
index
|
||||
for index, task in enumerate(self.tasks)
|
||||
if task.get("name") == PREFLIGHT
|
||||
)
|
||||
self.stage_wide = next(
|
||||
index
|
||||
for index, task in enumerate(self.tasks)
|
||||
if _parks(task) and _carrier(task).get("provider_view")
|
||||
)
|
||||
|
||||
def test_the_pre_flight_checks_read_a_carrier_in_every_deploy_mode(self):
|
||||
window = self.tasks[self.placement + 1 : self.preflight]
|
||||
parks = [task for task in window if _parks(task)]
|
||||
|
||||
self.assertEqual(
|
||||
len(parks),
|
||||
1,
|
||||
"one carrier must be parked between the add_host placement and the "
|
||||
"pre-flight checks, or every check renders the SPOT cold",
|
||||
)
|
||||
self.assertNotIn(
|
||||
"when",
|
||||
parks[0],
|
||||
"the pre-flight checks and the package batch read the SPOT in compose "
|
||||
"as in swarm, so the carrier must not depend on the deploy mode",
|
||||
)
|
||||
|
||||
def test_no_carrier_is_dropped_before_the_stage_wide_park(self):
|
||||
window = self.tasks[self.placement + 1 : self.stage_wide]
|
||||
|
||||
self.assertEqual(
|
||||
[task["name"] for task in window if _clears(task)],
|
||||
[],
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user