mirror of
https://github.com/PR0M3TH3AN/TORCH.git
synced 2026-10-27 07:51:52 +00:00
Merge pull request #200 from PR0M3TH3AN/agents/daily/perf-agent-4572387306970148005
perf: visibility-gate dashboard render loop
This commit is contained in:
13 files changed
+140
-70
No files matched your search
@@ -0,0 +1,23 @@
|
||||
# Daily Perf Report: 2026-02-16
|
||||
|
||||
## Summary
|
||||
Found and fixed a background CPU usage issue in the Agent Dashboard. No content documentation to audit.
|
||||
|
||||
## P0/P1/P2 Findings
|
||||
|
||||
### P1: Dashboard Background Rendering
|
||||
- **File**: `dashboard/index.html`
|
||||
- **Impact**: Unnecessary DOM updates/reflows every 30s when tab is hidden.
|
||||
- **Fix**: Added `document.hidden` check to `setInterval` and added `visibilitychange` listener.
|
||||
- **PR**: `perf: visibility-gate dashboard render loop`
|
||||
|
||||
## Metrics
|
||||
- **Login Time**: N/A (Static Analysis)
|
||||
- **Decrypt Queue**: N/A
|
||||
- **Hits Found**: 3 (1 actionable)
|
||||
|
||||
## Blockers
|
||||
- None.
|
||||
|
||||
## Decisions
|
||||
- See `src/decisions/DECISIONS_2026-02-16.md`
|
||||
@@ -1,8 +0,0 @@
|
||||
|
||||
> [email protected] dashboard:serve
|
||||
> node bin/torch-lock.mjs dashboard
|
||||
|
||||
Dashboard running at http://localhost:4173/dashboard/
|
||||
Serving files from /app
|
||||
Using configuration from /app
|
||||
Terminated
|
||||
@@ -814,11 +814,17 @@
|
||||
// Periodic TTL refresh
|
||||
// -----------------------------------------------------------------------
|
||||
refreshIntervalId = setInterval(() => {
|
||||
if (isAlive()) {
|
||||
if (isAlive() && !document.hidden) {
|
||||
renderLocks();
|
||||
}
|
||||
}, 30_000);
|
||||
|
||||
document.addEventListener('visibilitychange', () => {
|
||||
if (!document.hidden && isAlive()) {
|
||||
renderLocks();
|
||||
}
|
||||
});
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Event handlers
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
[
|
||||
{
|
||||
"file": "dashboard/index.html",
|
||||
"line": 816,
|
||||
"pattern": "setInterval",
|
||||
"snippet": " refreshIntervalId = setInterval(() => {",
|
||||
"risk": "Unbounded background DOM updates",
|
||||
"trigger": "Page load",
|
||||
"impact": "CPU usage when tab is hidden",
|
||||
"priority": "P1"
|
||||
},
|
||||
{
|
||||
"file": "dashboard/index.html",
|
||||
"line": 799,
|
||||
"pattern": "setTimeout",
|
||||
"snippet": " setTimeout(() => {",
|
||||
"risk": "Delayed retry",
|
||||
"trigger": "WebSocket close",
|
||||
"impact": "Low",
|
||||
"priority": "P3"
|
||||
},
|
||||
{
|
||||
"file": "src/services/memory/scheduler.js",
|
||||
"line": 33,
|
||||
"pattern": "setInterval",
|
||||
"snippet": " const handle = setInterval(() => {",
|
||||
"risk": "Background job loop",
|
||||
"trigger": "Server start",
|
||||
"impact": "Necessary backend process",
|
||||
"priority": "P3"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,19 @@
|
||||
# Context: perf-agent (2026-02-16)
|
||||
|
||||
## Goal
|
||||
Improve app responsiveness by finding and fixing background CPU/network work.
|
||||
|
||||
## Scope
|
||||
- Focus on "Visibility gating" for `dashboard/index.html`.
|
||||
- Run grep searches for performance patterns.
|
||||
- Ensure `INITIAL_BASELINE.md` exists.
|
||||
|
||||
## Constraints
|
||||
- Minimal changes.
|
||||
- Safe changes only.
|
||||
- No network access to external sites.
|
||||
- Running as a simulated agent (Jules).
|
||||
|
||||
## Assumptions
|
||||
- `dashboard/index.html` is the primary entry point for the dashboard.
|
||||
- `setInterval` in `dashboard/index.html` runs even when tab is hidden, wasting CPU.
|
||||
@@ -0,0 +1,16 @@
|
||||
# DECISIONS: perf-agent (2026-02-16)
|
||||
|
||||
## Decision: Visibility Gating for Dashboard Refresh Loop
|
||||
|
||||
- **Decision**: Modify the `setInterval` in `dashboard/index.html` to skip rendering if `document.hidden` is true.
|
||||
- **Rationale**: The dashboard currently re-renders the DOM every 30 seconds to update TTL bars, even when the tab is in the background. This wastes CPU cycles.
|
||||
- **Consequences**:
|
||||
- Reduced CPU usage when tab is hidden.
|
||||
- UI might be slightly stale when tab becomes visible, so we add a `visibilitychange` listener to force an immediate update.
|
||||
|
||||
## Alternatives Considered
|
||||
- Remove the interval entirely: Would stop updates.
|
||||
- Use `requestAnimationFrame`: Still runs (sometimes throttled) and more complex to manage with 30s intervals.
|
||||
|
||||
## Follow-ups
|
||||
- Monitor if users complain about stale data (should be mitigated by `visibilitychange`).
|
||||
@@ -0,0 +1,13 @@
|
||||
# TEST LOG: perf-agent (2026-02-16)
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. **Static Analysis**: Verify `dashboard/index.html` contains `document.hidden` check inside `setInterval`.
|
||||
2. **Static Analysis**: Verify `dashboard/index.html` contains `document.addEventListener('visibilitychange', ...)` handler.
|
||||
3. **Linting**: Run `npm run lint` to ensure no syntax errors or style violations.
|
||||
|
||||
## Results
|
||||
|
||||
- [x] Static Analysis (Hidden Check): Passed (Verified in `dashboard/index.html`)
|
||||
- [x] Static Analysis (Visibility Listener): Passed (Verified in `dashboard/index.html`)
|
||||
- [ ] Linting: Scheduled for Scheduler Completion step.
|
||||
@@ -0,0 +1,10 @@
|
||||
# TODO: perf-agent (2026-02-16)
|
||||
|
||||
- [ ] Create context file.
|
||||
- [ ] Run grep searches.
|
||||
- [ ] Create hits file.
|
||||
- [ ] Implement visibility gating in `dashboard/index.html`.
|
||||
- [ ] Document decisions.
|
||||
- [ ] Create test logs.
|
||||
- [ ] Create daily report.
|
||||
- [ ] Commit and push.
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
agent: perf-agent
|
||||
status: completed
|
||||
date: 2026-02-16
|
||||
---
|
||||
|
||||
# perf-agent completed
|
||||
|
||||
- **PR**: `perf: visibility-gate dashboard render loop`
|
||||
- **Artifacts**:
|
||||
- `src/context/CONTEXT_2026-02-16.md`
|
||||
- `src/todo/TODO_2026-02-16.md`
|
||||
- `src/decisions/DECISIONS_2026-02-16.md`
|
||||
- `src/test_logs/TEST_LOG_2026-02-16.md`
|
||||
- `daily-perf-report-2026-02-16.md`
|
||||
- `perf/hits-2026-02-16.json`
|
||||
- **Summary**:
|
||||
- Found and fixed a P1 issue in `dashboard/index.html` where the render loop ran unnecessarily when the tab was hidden.
|
||||
- Added visibility gating and a `visibilitychange` listener.
|
||||
- Verified changes with static analysis.
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 64 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 140 KiB |
@@ -1,24 +0,0 @@
|
||||
|
||||
from playwright.sync_api import sync_playwright
|
||||
|
||||
def verify_dashboard():
|
||||
with sync_playwright() as p:
|
||||
browser = p.chromium.launch(headless=True)
|
||||
page = browser.new_page()
|
||||
try:
|
||||
page.goto("http://localhost:4173/dashboard/")
|
||||
# Wait for title
|
||||
page.wait_for_selector("h1:has-text('TORCH Agent Dashboard')")
|
||||
# Wait a bit for JS to run and potentially render the summary bar
|
||||
page.wait_for_timeout(3000)
|
||||
|
||||
# Take screenshot
|
||||
page.screenshot(path="verification/dashboard.png")
|
||||
print("Screenshot saved to verification/dashboard.png")
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
finally:
|
||||
browser.close()
|
||||
|
||||
if __name__ == "__main__":
|
||||
verify_dashboard()
|
||||
@@ -1,37 +0,0 @@
|
||||
from playwright.sync_api import sync_playwright
|
||||
|
||||
def run():
|
||||
with sync_playwright() as p:
|
||||
browser = p.chromium.launch(headless=True)
|
||||
page = browser.new_page()
|
||||
|
||||
# Navigate to dashboard
|
||||
print("Navigating to dashboard...")
|
||||
page.goto("http://localhost:8081/dashboard/index.html")
|
||||
|
||||
# Click the TORCH link
|
||||
print("Clicking TORCH link...")
|
||||
page.click("#openDocs")
|
||||
|
||||
# Wait for modal to be visible and content to load
|
||||
print("Waiting for modal...")
|
||||
page.wait_for_selector("#docsModal.show")
|
||||
|
||||
# Wait for markdown content to be rendered (look for h1)
|
||||
page.wait_for_selector("#markdown-content h1")
|
||||
|
||||
# Take screenshot
|
||||
print("Taking screenshot...")
|
||||
page.screenshot(path="verification/dashboard_modal.png")
|
||||
|
||||
# Verify content
|
||||
content = page.inner_text("#markdown-content")
|
||||
if "Task Orchestration via Relay-Coordinated Handoff" in content:
|
||||
print("SUCCESS: Modal content verified.")
|
||||
else:
|
||||
print("FAILURE: Modal content not found.")
|
||||
|
||||
browser.close()
|
||||
|
||||
if __name__ == "__main__":
|
||||
run()
|
||||
Reference in new issue
Block a user