Backend Improvements (11 fixes applied): Critical Fixes: - Add lock protection for browser pool access in monitor stats - Ensure async track_janitor_event across all call sites - Improve error handling in monitor request tracking (already in place) Important Fixes: - Replace fire-and-forget Redis with background persistence worker - Add time-based expiry for completed requests/errors (5min cleanup) - Implement input validation for monitor route parameters - Add 4s timeout to timeline updater to prevent hangs - Add warning when killing browsers with active requests - Implement monitor cleanup on shutdown with final persistence - Document memory estimates with TODO for actual tracking Frontend Enhancements: WebSocket Real-time Updates: - Add WebSocket endpoint at /monitor/ws for live monitoring - Implement auto-reconnect with exponential backoff (max 5 attempts) - Add graceful fallback to HTTP polling on WebSocket failure - Send comprehensive updates every 2 seconds (health, requests, browsers, timeline, events) UI/UX Improvements: - Add live connection status indicator with pulsing animation - Green "Live" = WebSocket connected - Yellow "Connecting..." = Attempting connection - Blue "Polling" = Fallback to HTTP polling - Red "Disconnected" = Connection failed - Restore original beautiful styling for all sections - Improve request table layout with flex-grow for URL column - Add browser type text labels alongside emojis - Add flex layout to browser section header Testing: - Add test-websocket.py for WebSocket validation - All 7 integration tests passing successfully Summary: 563 additions across 6 files
35 lines
1.0 KiB
Python
Executable File
35 lines
1.0 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
Quick WebSocket test - Connect to monitor WebSocket and print updates
|
|
"""
|
|
import asyncio
|
|
import websockets
|
|
import json
|
|
|
|
async def test_websocket():
|
|
uri = "ws://localhost:11235/monitor/ws"
|
|
print(f"Connecting to {uri}...")
|
|
|
|
try:
|
|
async with websockets.connect(uri) as websocket:
|
|
print("✅ Connected!")
|
|
|
|
# Receive and print 5 updates
|
|
for i in range(5):
|
|
message = await websocket.recv()
|
|
data = json.loads(message)
|
|
print(f"\n📊 Update #{i+1}:")
|
|
print(f" - Health: CPU {data['health']['container']['cpu_percent']}%, Memory {data['health']['container']['memory_percent']}%")
|
|
print(f" - Active Requests: {len(data['requests']['active'])}")
|
|
print(f" - Browsers: {len(data['browsers'])}")
|
|
|
|
except Exception as e:
|
|
print(f"❌ Error: {e}")
|
|
return 1
|
|
|
|
print("\n✅ WebSocket test passed!")
|
|
return 0
|
|
|
|
if __name__ == "__main__":
|
|
exit(asyncio.run(test_websocket()))
|