package track1 import ( "context" "encoding/json" "fmt" "net/http" "time" ) // HandleMissionControlStream sends periodic text/event-stream payloads with full bridge/status data (for SPA or tooling). func (s *Server) HandleMissionControlStream(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet { writeError(w, http.StatusMethodNotAllowed, "method_not_allowed", "Method not allowed") return } controller := http.NewResponseController(w) w.Header().Set("Content-Type", "text/event-stream") w.Header().Set("Cache-Control", "no-cache") w.Header().Set("Connection", "keep-alive") w.Header().Set("X-Accel-Buffering", "no") // Immediate event so nginx unbuffers and short curl probes see `event:`/`data:` before RPC probes finish. _, _ = fmt.Fprintf(w, ": mission-control stream\n\nevent: ping\ndata: {}\n\n") _ = controller.Flush() tick := time.NewTicker(20 * time.Second) defer tick.Stop() send := func() bool { ctx, cancel := context.WithTimeout(r.Context(), 12*time.Second) defer cancel() data := s.BuildBridgeStatusData(ctx) payload, err := json.Marshal(map[string]interface{}{"data": data}) if err != nil { return false } _, _ = fmt.Fprintf(w, "event: mission-control\ndata: %s\n\n", payload) return controller.Flush() == nil } if !send() { return } for { select { case <-r.Context().Done(): return case <-tick.C: if !send() { return } } } }