Skip to content

customizations endpoint re-reads every source file per request; the page refetches on any SSE event #28

Description

@paddymul

Problem

GET /{project}/api/customizations (app.py:1011) returns all three customization registries by calling list_stats, list_display_klasses, and list_post_processings (app.py:10221024). Each helper read_text()s every file in its registry on every call — active and disabled alike (summary_stats.py:92/103, display_klasses.py:136/145, post_processing.py:92/103); there is no caching or mtime check. On the client, CustomizationsPage refetches the whole payload whenever the SSE version changes, and version increments on every server event, not just customization edits (SSEContext.tsx:29). So an unrelated event — an entry build, a notebook reorder, an alias change — triggers a full re-read of every summary-stat, display-klass, and post-processing source file from disk.

Impact

Negligible at current scale: a handful of small Python files per registry, on a page few people keep open. But the cost is O(files × events) disk reads with no caching, the entire payload reloads when only one registry — or none — actually changed, and it grows with both registry size and overall event volume.

Suggested fix

Gate the client refetch on customization-relevant events. lastEvent.kind is already exposed (SSEContext.tsx:29) and the mutating MCP tools emit summary_stat_changed / display_changed / post_processing_changed (server.py:909/991/1073), so the page can refetch only on those kinds instead of the raw version counter. The per-request disk reads are cheap enough to leave as-is; if they ever aren't, an mtime-keyed cache inside the list_* helpers would cover every caller.

Context

Identified during review of #26 (the read-only customizations page). Demo-scale projects are unaffected; flagging as the growth vector if registries or event volume grow.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions