mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-10 12:47:04 +00:00
perf(sys-dns-cloudflare-records): poll record jobs every second while collecting
The collect step polled each async record job every 5 s, so a job that finished right after a poll idled up to 5 s before its result was read. The interval is now cloudflare_collect_interval (1 s), and the poll cap derives from it, so the attempt's collect deadline, the retry split and ignore_errors behave exactly as before. 🎯 Fix: 92 % 💥 Break: 3 % 🌱 Efficiency: – ⚡ Speed: – 🛡️ Security: ~100 % 🏆 Score: 89 🚦 Gate: ✅ 90/5, efficiency and speed <= 100, security 100 % Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
59889bb5af
commit
f51ab74697
4 files changed
+79
-2
No files matched your search
@@ -7,7 +7,8 @@ cloudflare_request_timeout: 20 # Seconds one Cloudflare HTTP socket operation ma
|
||||
cloudflare_attempt_timeout: 60 # Seconds one record job may run before async_wrapper kills it as hung
|
||||
cloudflare_attempts: 3 # Attempts per record; only hangs, timeouts, connection errors, 429 and 5xx earn another
|
||||
cloudflare_retry_delay: 10 # Seconds between two attempts
|
||||
cloudflare_collect_retries: "{{ ((lookup('timeout', cloudflare_attempt_timeout | int) | int) / 5) | round(0, 'ceil') | int + 2 }}" # Cap on 5 s polls per job; the attempt's collect deadline ends them sooner
|
||||
cloudflare_collect_interval: 1 # Seconds between two polls of one record job while collecting
|
||||
cloudflare_collect_retries: "{{ ((lookup('timeout', cloudflare_attempt_timeout | int) | int) / (cloudflare_collect_interval | int)) | round(0, 'ceil') | int + 2 }}" # Cap on polls per job; the attempt's collect deadline ends them sooner
|
||||
cloudflare_tolerate: # Substrings of an answer that mean the record already stands as wanted
|
||||
- "An identical record already exists"
|
||||
- "code: 81058"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
register: _cf_reaped
|
||||
until: _cf_reaped.finished or (now(utc=true).timestamp() > (_cf_collect_deadline | float))
|
||||
retries: "{{ cloudflare_collect_retries | int }}"
|
||||
delay: 5
|
||||
delay: "{{ cloudflare_collect_interval | int }}"
|
||||
changed_when: false
|
||||
ignore_errors: true
|
||||
when: ASYNC_ENABLED | bool
|
||||
|
||||
Whitespace-only changes.
@@ -0,0 +1,76 @@
|
||||
import unittest
|
||||
|
||||
from jinja2 import Environment, StrictUndefined
|
||||
|
||||
from plugins.lookup.timeout import scaled_timeout
|
||||
from utils import PROJECT_ROOT
|
||||
from utils.cache.yaml import load_yaml, load_yaml_any
|
||||
from utils.roles.mapping import ROLE_FILE_DEFAULTS_MAIN
|
||||
|
||||
ROLE = PROJECT_ROOT / "roles" / "sys-dns-cloudflare-records"
|
||||
|
||||
|
||||
def _defaults() -> dict:
|
||||
return load_yaml(str(ROLE / ROLE_FILE_DEFAULTS_MAIN))
|
||||
|
||||
|
||||
def _collect_task() -> dict:
|
||||
return next(
|
||||
task
|
||||
for task in load_yaml_any(str(ROLE / "tasks" / "judge.yml"))
|
||||
if "ansible.builtin.async_status" in task
|
||||
)
|
||||
|
||||
|
||||
def _render(expression: str, variables: dict, factor: int):
|
||||
"""
|
||||
Args:
|
||||
expression: one templated value of the role.
|
||||
variables: the role defaults the expression may read.
|
||||
factor: the ``TIMEOUT_FACTOR`` the ``timeout`` lookup scales by.
|
||||
|
||||
Returns:
|
||||
The rendered value as an integer.
|
||||
"""
|
||||
environment = Environment(undefined=StrictUndefined, autoescape=True)
|
||||
environment.globals["lookup"] = lambda name, base: scaled_timeout(base, factor)
|
||||
return int(environment.from_string(str(expression)).render(**variables))
|
||||
|
||||
|
||||
class TestCollectPolling(unittest.TestCase):
|
||||
def test_collect_polls_at_the_role_interval_and_retries_by_it(self):
|
||||
defaults = _defaults()
|
||||
task = _collect_task()
|
||||
|
||||
self.assertEqual(task["delay"], "{{ cloudflare_collect_interval | int }}")
|
||||
self.assertEqual(task["retries"], "{{ cloudflare_collect_retries | int }}")
|
||||
self.assertIn(
|
||||
"cloudflare_collect_interval", defaults["cloudflare_collect_retries"]
|
||||
)
|
||||
self.assertIn("_cf_collect_deadline", task["until"])
|
||||
|
||||
def test_the_polling_window_covers_the_attempt_timeout(self):
|
||||
defaults = _defaults()
|
||||
task = _collect_task()
|
||||
for factor in (1, 2, 3):
|
||||
for interval in (1, 2, 5, 7):
|
||||
with self.subTest(factor=factor, interval=interval):
|
||||
variables = dict(defaults, cloudflare_collect_interval=interval)
|
||||
variables["cloudflare_collect_retries"] = _render(
|
||||
defaults["cloudflare_collect_retries"], variables, factor
|
||||
)
|
||||
retries = _render(task["retries"], variables, factor)
|
||||
delay = _render(task["delay"], variables, factor)
|
||||
attempt = scaled_timeout(
|
||||
defaults["cloudflare_attempt_timeout"], factor
|
||||
)
|
||||
|
||||
self.assertEqual(delay, interval)
|
||||
self.assertGreaterEqual(retries * delay, attempt)
|
||||
|
||||
def test_the_default_interval_is_one_second(self):
|
||||
self.assertEqual(_defaults()["cloudflare_collect_interval"], 1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user