Skip to content

Snapshot AppState before rendering to shorten the TUI critical section #136

Description

@inureyes

Problem / Background

Even after the screen update is throttled, the current TUI render path still holds the shared AppState lock while it decides whether to render and while it assembles frame content.

That means UI rendering and background data collection contend on the same critical section longer than necessary. On busy systems or large remote views, this increases the chance of:

  • delayed collector updates
  • delayed input handling while the UI is preparing a frame
  • inconsistent responsiveness under load

To make the UI both smoother and cheaper, the render path should stop treating AppState itself as the frame model.

Proposed Solution

Introduce a dedicated render snapshot / view model that is captured quickly from AppState, after which the mutex is released before expensive frame composition begins.

This issue should build on the event-driven wakeup path from #135.

Scope

Snapshot-based rendering

  • Define a render snapshot structure containing only the data needed for one frame
  • Capture the snapshot under lock and release the lock immediately afterward
  • Move string/buffer composition to operate on the snapshot instead of the live shared state

Critical section reduction

  • Audit the UI loop to minimize the duration of AppState mutex ownership
  • Ensure expensive work such as filtering, formatting, and content assembly happens after the lock is released
  • Avoid any await points while holding the render-state lock

Mutable UI state boundaries

  • Separate persistent UI-only state from collector-owned state where appropriate
  • Revisit frame counters / scroll bookkeeping so only truly mutable frame state remains in the shared state object
  • Keep notification and resize behavior correct after the snapshot split

Acceptance Criteria

  • The render path no longer holds AppState for the full frame composition path
  • Background collectors can update state without waiting on long render-time critical sections
  • Input handling remains correct while the new snapshot path is in use
  • Rendered output remains functionally identical to the current UI behavior
  • The new snapshot structure is small enough and well-scoped enough to support future caching work

Integration and Verification Requirements

  • The implementation must be verified by actually running the affected code path and confirming the intended behavior works end-to-end
  • Verification must cover both behavior correctness and the expected performance/responsiveness improvement for this issue
  • The final result must be integrated into the existing project flow, not left behind as an isolated module, helper, or function that is not exercised by the real application path
  • Completion is not satisfied by adding code alone; the change must be wired into the real local/remote TUI execution path and confirmed to be active in practice

Technical Considerations

  • Snapshot creation introduces cloning cost; the design should minimize unnecessary duplication while still keeping the lock duration short.
  • Shared large collections may benefit from pre-derived lightweight frame structures instead of cloning everything blindly.
  • This issue should be treated as the second implementation step, after Reduce TUI idle CPU and improve responsiveness with event-driven UI wakeups #135, because the wakeup model defines when a frame is needed and the snapshot model defines how that frame is built.

Metadata

Metadata

Assignees

No one assigned

    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