Skip to content

[BUG] x86: Renderer hangs indefinitely on network interruption mid-page-load — no webpage load timeout #2999

Description

@agattis

Description

When a network interruption occurs while AnthiasWebview is mid-fetch of a complex web page, the QtWebEngineProcess --type=renderer stalls indefinitely waiting on pending network I/O. All subsequent loadPage() D-Bus calls are silently ignored — the renderer is busy and cannot accept new navigation requests. The display freezes on the last committed Wayland buffer permanently until the container is restarted.

This is distinct from GPU/DRM-related freezes. The system is otherwise healthy throughout.

Steps to Reproduce

Steps to reproduce the behavior:

  1. Add a series of complex webpage
  2. Unplug network (wifi most pronounced) randomly

Expected Behavior

The display should continue attempting to show assets.

Environment

  • Device: Dell OptiPlex Micro (Intel HD Graphics 530, i915 driver)
  • OS: Debian Trixie (x86_64)
  • Anthias Version: latest-x86 (June 2026)
  • Installation: Standard curl installer

Symptoms

  • Display freezes on last rendered frame
  • anthias-viewer Python scheduler logs continue cycling normally — it advances through assets on schedule
  • AnthiasWebview process alive, two QtWebEngineProcess --type=renderer entries visible in ps aux, both at 0% CPU with identical accumulated runtimes
  • No OOM kills, no GPU errors, no DRM errors in logs
  • dmesg shows WiFi dropout immediately preceding the freeze:
iwlwifi: missed_beacons:20, missed_beacons_since_rx:2
wlan0: Connection to AP lost
wlan0: Connection to AP lost   ← second dropout 9 seconds later
  • Container restart recovers the display

Root Cause

The Python scheduler in scheduling.py correctly advances to the next asset after the configured duration — which is why logs look normal. However, loadPage() is a fire-and-forget D-Bus call with no acknowledgment or completion signal on the Python side.
When a QtWebEngineProcess --type=renderer stalls mid-fetch due to a network interruption, it stays alive but frozen — waiting on I/O that will never complete. Subsequent loadPage() D-Bus calls arrive at AnthiasWebview, but the renderer cannot accept new navigation requests while busy. No new Wayland surface buffer is ever committed, so cage has nothing to display and the screen stays frozen.
Chromium spawned a second renderer process for the next asset, which also stalled — visible as two renderer processes at 0% CPU.

Possible Missing Timeout

media_player.py defines VIDEO_TIMEOUT = 20 for video assets, providing a safety net when video playback stalls. No equivalent exists for web page loads:

Confirmed Workarounds Applied

  1. Disable WiFi power management (prevents the triggering dropout)
  2. Enable Chromium disk cache (allows cached pages to render during brief dropouts)

These reduce the frequency of the issue but do not eliminate it — any network interruption long enough to stall an active fetch will still trigger the hang.

Suggested Fix

Add a QTimer-based page load watchdog in AnthiasWebview (C++ Qt side). If loadFinished has not fired within a configurable timeout, stop the current load and force navigation to the next asset:

// In AnthiasWebview, when loadPage() is called:
m_loadTimer->start(15000); // 15 second timeout

// Connect loadFinished to cancel the timer on success:
connect(m_page, &QWebEnginePage::loadFinished, m_loadTimer, &QTimer::stop);

// On timeout, stop and signal the viewer to advance:
connect(m_loadTimer, &QTimer::timeout, this, [this]() {
    m_page->triggerAction(QWebEnginePage::Stop);
    // emit signal or call next asset via D-Bus
});

This would self-recover from both network dropouts and renderer stalls without requiring a full container restart, and would bring web page reliability in line with the existing VIDEO_TIMEOUT behavior for video assets.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions