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:
- Add a series of complex webpage
- 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
- Disable WiFi power management (prevents the triggering dropout)
- 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.
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:
Expected Behavior
The display should continue attempting to show assets.
Environment
Symptoms
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
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:
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.