perf: move blocking homepage and hash I/O off loop
Quality Gate / gate (push) Failing after 47s

Co-authored-by: Copilot App <[email protected]>
This commit is contained in:
Jim Lancaster
2026-08-23 18:41:01 -05:00
co-authored by Copilot App
parent 2093eb6fb3
commit 3873810022
9 changed files with 43 additions and 12 deletions
+1 -1
View File
@@ -59,7 +59,7 @@ async def _lifespan(app: FastAPI):
stop_event, worker_notifier, worker_health = await stack.enter_async_context(
worker_consumer_lifespan(
session_factory=app.state.runtime.session_factory,
poll_interval_seconds=1.0,
poll_interval_seconds=settings.worker_poll_interval_seconds,
shutdown_timeout_seconds=(
settings.worker_provider_timeout_seconds + settings.worker_shutdown_grace_seconds
),
+1
View File
@@ -117,6 +117,7 @@ class Settings(BaseSettings):
worker_stale_job_seconds: float = Field(default=30.0, gt=0.0)
worker_retry_backoff_seconds: float = Field(default=1.0, ge=0.0)
worker_shutdown_grace_seconds: float = Field(default=5.0, ge=0.0)
worker_poll_interval_seconds: float = Field(default=1.0, gt=0.0)
worker_min_transcription_chars: int = Field(default=0, ge=0)
worker_min_transcription_lines: int = Field(default=0, ge=0)
worker_fail_on_finish_reason_length: bool = False
+6 -1
View File
@@ -1,5 +1,6 @@
from __future__ import annotations
import asyncio
import hashlib
import logging
from collections.abc import Sequence
@@ -398,6 +399,10 @@ async def store_source_file(
)
return StoredSourceFile(
path=stored_path,
file_hash=hashlib.sha256(file_bytes).hexdigest(),
file_hash=await asyncio.to_thread(_sha256_hexdigest, file_bytes),
file_size_bytes=len(file_bytes),
)
def _sha256_hexdigest(data: bytes) -> str:
return hashlib.sha256(data).hexdigest()
+27 -8
View File
@@ -2,6 +2,7 @@
from __future__ import annotations
import asyncio
from collections.abc import Callable
from fastapi import Request
@@ -116,7 +117,7 @@ def _render_homepage_view(*, markdown_text: str, render_image_panel: Callable[[]
ui.element("div")
def _render_homepage_editor(*, render_image_panel, markdown_input, on_upload) -> None:
def _render_homepage_editor(*, render_image_panel, markdown_input, on_upload, initial_markdown: str) -> None:
with ui.grid().classes("w-full grid-cols-12 gap-4"):
with ui.column().classes("col-span-12 lg:col-span-4 gap-4"):
with archival_card(title="Homepage Image"):
@@ -132,7 +133,7 @@ def _render_homepage_editor(*, render_image_panel, markdown_input, on_upload) ->
markdown_input[0] = (
ui.textarea(
label="Homepage markdown",
value=read_homepage_markdown(),
value=initial_markdown,
)
.props("outlined autogrow")
.classes("w-full")
@@ -152,6 +153,7 @@ def register_page() -> None: # noqa: PLR0915
render_navigation_header(current_path="/homepage")
photos = await photos_service.list_photos(person_id=None)
active_index = [0]
homepage_markdown = [""]
@ui.refreshable
def render_image_panel() -> None:
@@ -172,12 +174,20 @@ def register_page() -> None: # noqa: PLR0915
on_click=lambda: ui.navigate.to("/homepage/edit"),
icon="edit",
).classes("ui-btn-primary text-xs")
_render_homepage_view(
markdown_text=read_homepage_markdown().strip(),
render_image_panel=render_image_panel,
)
@ui.page("/homepage/edit", title="Edit Homepage")
@ui.refreshable
def render_home_content() -> None:
_render_homepage_view(
markdown_text=homepage_markdown[0].strip(),
render_image_panel=render_image_panel,
)
render_home_content()
homepage_markdown[0] = await asyncio.to_thread(read_homepage_markdown, settings)
render_home_content.refresh()
@ui.page("/homepage/edit", title="Edit Home Page")
async def homepage_edit_page(request: Request, session_factory: SessionFactoryDep) -> None: # noqa: PLR0915
photos_service = PhotosService(session_factory=session_factory)
settings = resolve_runtime_settings(request)
@@ -268,7 +278,11 @@ def register_page() -> None: # noqa: PLR0915
ui.navigate.to("/homepage/edit")
async def save_homepage() -> None:
save_homepage_markdown((markdown_input[0].value if markdown_input[0] is not None else "") or "")
await asyncio.to_thread(
save_homepage_markdown,
(markdown_input[0].value if markdown_input[0] is not None else "") or "",
settings,
)
ui.notify("Homepage saved", type="positive")
ui.navigate.to("/homepage")
@@ -283,4 +297,9 @@ def register_page() -> None: # noqa: PLR0915
render_image_panel=render_image_panel,
markdown_input=markdown_input,
on_upload=on_upload,
initial_markdown="",
)
loaded_markdown = await asyncio.to_thread(read_homepage_markdown, settings)
if markdown_input[0] is not None:
markdown_input[0].value = loaded_markdown
+3 -2
View File
@@ -2,6 +2,7 @@
from __future__ import annotations
import asyncio
from typing import Any
from uuid import UUID
@@ -540,8 +541,8 @@ async def _recover_prompt(prompts: PromptStore, name: str) -> None:
async def _read_home_page_text(settings: Settings) -> str:
return read_homepage_markdown(settings=settings)
return await asyncio.to_thread(read_homepage_markdown, settings=settings)
async def _write_home_page_text(settings: Settings, markdown_text: str) -> None:
save_homepage_markdown(markdown_text, settings=settings)
await asyncio.to_thread(save_homepage_markdown, markdown_text, settings=settings)