Bc-AI commited on
Commit
3520809
Β·
verified Β·
1 Parent(s): bdd11d5

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +85 -9
app.py CHANGED
@@ -184,12 +184,13 @@ async def check_worker_health(worker_url: str) -> bool:
184
 
185
  async def health_check_loop():
186
  while True:
 
187
  for worker_url in WORKER_URLS:
188
  healthy = await check_worker_health(worker_url)
189
  worker_health[worker_url]["healthy"] = healthy
190
  worker_health[worker_url]["last_check"] = time.time()
191
 
192
- # Broadcast to dashboard
193
  await broadcast_stats()
194
 
195
  await asyncio.sleep(HEALTH_CHECK_INTERVAL)
@@ -694,16 +695,91 @@ async def dashboard():
694
  </div>
695
 
696
  <script>
697
- const ws = new WebSocket(`ws://${window.location.host}/ws`);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
698
 
699
- ws.onmessage = (event) => {
700
- const data = JSON.parse(event.data);
701
- updateDashboard(data);
702
- };
703
 
704
- ws.onerror = () => {
705
- console.error('WebSocket error');
706
- };
707
 
708
  function updateDashboard(data) {
709
  // Mode
 
184
 
185
  async def health_check_loop():
186
  while True:
187
+ # Check all workers
188
  for worker_url in WORKER_URLS:
189
  healthy = await check_worker_health(worker_url)
190
  worker_health[worker_url]["healthy"] = healthy
191
  worker_health[worker_url]["last_check"] = time.time()
192
 
193
+ # Always broadcast stats to connected clients
194
  await broadcast_stats()
195
 
196
  await asyncio.sleep(HEALTH_CHECK_INTERVAL)
 
695
  </div>
696
 
697
  <script>
698
+ // Use wss:// for HTTPS, ws:// for HTTP
699
+ const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
700
+ let ws;
701
+ let usePolling = false;
702
+
703
+ function connectWebSocket() {
704
+ try {
705
+ ws = new WebSocket(`${protocol}//${window.location.host}/ws`);
706
+
707
+ ws.onopen = () => {
708
+ console.log('βœ… WebSocket connected');
709
+ usePolling = false;
710
+ };
711
+
712
+ ws.onmessage = (event) => {
713
+ const data = JSON.parse(event.data);
714
+ updateDashboard(data);
715
+ };
716
+
717
+ ws.onerror = (error) => {
718
+ console.error('❌ WebSocket error, switching to polling');
719
+ usePolling = true;
720
+ startPolling();
721
+ };
722
+
723
+ ws.onclose = () => {
724
+ console.log('πŸ”Œ WebSocket disconnected');
725
+ if (!usePolling) {
726
+ setTimeout(connectWebSocket, 3000);
727
+ }
728
+ };
729
+ } catch (e) {
730
+ console.error('Failed to connect WebSocket, using polling');
731
+ usePolling = true;
732
+ startPolling();
733
+ }
734
+ }
735
+
736
+ async function pollStats() {
737
+ if (!usePolling) return;
738
+
739
+ try {
740
+ const response = await fetch('/api/status');
741
+ const data = await response.json();
742
+
743
+ // Fetch worker stats too
744
+ const workersRes = await fetch('/workers');
745
+ const workersData = await workersRes.json();
746
+
747
+ // Format data like WebSocket
748
+ const formattedData = {
749
+ timestamp: Date.now() / 1000,
750
+ mode: data.mode,
751
+ load: data.current_load,
752
+ workers: workersData.workers.map(w => ({
753
+ url: w.url.split("//")[1].split(".")[0],
754
+ healthy: w.healthy,
755
+ active: w.active_requests || 0,
756
+ total: 0,
757
+ tokens: 0,
758
+ latency: 0,
759
+ role: "idle"
760
+ })),
761
+ cluster: {
762
+ total_requests: 0,
763
+ successful: 0,
764
+ failed: 0,
765
+ uptime: 0,
766
+ rps: 0
767
+ }
768
+ };
769
+
770
+ updateDashboard(formattedData);
771
+ } catch (e) {
772
+ console.error('Polling error:', e);
773
+ }
774
+ }
775
 
776
+ function startPolling() {
777
+ pollStats();
778
+ setInterval(pollStats, 1000);
779
+ }
780
 
781
+ // Try WebSocket first
782
+ connectWebSocket();
 
783
 
784
  function updateDashboard(data) {
785
  // Mode