Defer office runtime preparation during startup
Some checks are pending
Build And Publish Docker Images / plan (push) Waiting to run
Build And Publish Docker Images / build (push) Blocked by required conditions

This commit is contained in:
Alessandro 2026-05-04 23:04:06 +02:00
parent 2d389af727
commit d326513983
2 changed files with 60 additions and 6 deletions

View file

@ -1,16 +1,47 @@
from __future__ import annotations
import threading
from typing import Any
from helpers.extension import Extension
from helpers.print_style import PrintStyle
from plugins._office import hooks
from plugins._office.helpers import libreoffice_desktop_routes
_startup_preparation_thread: threading.Thread | None = None
class OfficeStartupCleanup(Extension):
def execute(self, **kwargs):
libreoffice_desktop_routes.install_route_hooks()
result = hooks.cleanup_stale_runtime_state()
if result.get("errors"):
PrintStyle.warning("Office runtime preparation reported errors:", result["errors"])
elif result.get("installed") or result.get("removed"):
PrintStyle.info("Office runtime prepared:", result)
_start_background_runtime_preparation()
def _start_background_runtime_preparation() -> threading.Thread:
global _startup_preparation_thread
if _startup_preparation_thread and _startup_preparation_thread.is_alive():
return _startup_preparation_thread
_startup_preparation_thread = threading.Thread(
target=_prepare_runtime_safely,
name="a0-office-runtime-preparation",
daemon=True,
)
_startup_preparation_thread.start()
return _startup_preparation_thread
def _prepare_runtime_safely() -> None:
try:
_log_runtime_preparation_result(hooks.cleanup_stale_runtime_state())
except Exception as exc:
PrintStyle.warning("Office runtime preparation failed:", exc)
def _log_runtime_preparation_result(result: dict[str, Any]) -> None:
if result.get("errors"):
PrintStyle.warning("Office runtime preparation reported errors:", result["errors"])
elif result.get("installed") or result.get("removed"):
PrintStyle.info("Office runtime prepared:", result)

View file

@ -686,6 +686,8 @@ def test_cleanup_hook_removes_stale_runtime_state_idempotently(tmp_path, monkeyp
def test_office_startup_defers_persistent_desktop_runtime(monkeypatch):
calls = []
cleanup_calls = []
started_threads = []
routes_module = types.ModuleType("plugins._office.helpers.libreoffice_desktop_routes")
routes_module.install_route_hooks = lambda: calls.append("routes")
monkeypatch.setitem(sys.modules, "plugins._office.helpers.libreoffice_desktop_routes", routes_module)
@ -700,14 +702,35 @@ def test_office_startup_defers_persistent_desktop_runtime(monkeypatch):
monkeypatch.setattr(
office_startup.hooks,
"cleanup_stale_runtime_state",
lambda: {"ok": True, "errors": [], "installed": [], "removed": []},
lambda: cleanup_calls.append("cleanup") or {"ok": True, "errors": [], "installed": [], "removed": []},
)
class FakeThread:
def __init__(self, *, target, name, daemon):
self.target = target
self.name = name
self.daemon = daemon
def is_alive(self):
return False
def start(self):
started_threads.append(self)
monkeypatch.setattr(office_startup.threading, "Thread", FakeThread)
office_startup.OfficeStartupCleanup(agent=None).execute()
assert calls == ["routes"]
assert cleanup_calls == []
assert len(started_threads) == 1
assert started_threads[0].name == "a0-office-runtime-preparation"
assert started_threads[0].daemon is True
assert not hasattr(office_startup, "libreoffice_desktop")
started_threads[0].target()
assert cleanup_calls == ["cleanup"]
def test_cleanup_hook_reruns_when_stale_packages_exist_after_old_marker(tmp_path, monkeypatch):
marker = tmp_path / "state" / "cleanup.done"