MCPcopy Create free account
hub / github.com/rilldata/rill / SSEHandler

Method SSEHandler

runtime/server/sse.go:53–275  ·  view source on GitHub ↗

SSEHandler is a shim that exposes a unified SSE endpoint for the Server's streaming gRPC RPCs. This is useful for two reasons: 1. The vanguard library doesn't currently map streaming RPCs to SSE, so we need to manually implement that. 2. We need to provide a unified endpoint that can multiplex multi

(w http.ResponseWriter, req *http.Request)

Source from the content-addressed store, hash-verified

51// - logs_replay_limit: maps to WatchLogsRequest.ReplayLimit
52// - logs_level: maps to WatchLogsRequest.Level
53func (s *Server) SSEHandler(w http.ResponseWriter, req *http.Request) {
54 // Parse the instance ID
55 instanceID := req.PathValue("instance_id")
56
57 // Parse the event(s) to subscribe to.
58 var eventTypes []string
59 var omitEventNames bool
60 q := req.URL.Query()
61 if v := q.Get("events"); v != "" {
62 eventTypes = strings.Split(v, ",")
63 }
64 if v := q.Get("stream"); v != "" { // For backwards compatibility, see function comment.
65 if len(eventTypes) > 0 {
66 http.Error(w, "cannot specify both 'stream' and 'events' parameters", http.StatusBadRequest)
67 return
68 }
69 omitEventNames = true
70 switch v {
71 case "files":
72 eventTypes = []string{sseEventFile}
73 case "resources":
74 eventTypes = []string{sseEventResource}
75 case "logs":
76 eventTypes = []string{sseEventLog}
77 default:
78 http.Error(w, fmt.Sprintf("unknown stream type %q", v), http.StatusBadRequest)
79 return
80 }
81 }
82
83 // Deduplicate to prevent starting multiple goroutines for the same event type.
84 slices.Sort(eventTypes)
85 eventTypes = slices.Compact(eventTypes)
86
87 // Add observability attributes
88 observability.AddRequestAttributes(req.Context(),
89 attribute.String("args.instance_id", instanceID),
90 attribute.StringSlice("args.events", eventTypes),
91 )
92
93 // Validation
94 if len(eventTypes) == 0 {
95 http.Error(w, "must specify at least one event type via the 'events' parameter", http.StatusBadRequest)
96 return
97 }
98
99 // Check controller is open
100 if _, err := s.runtime.Controller(req.Context(), instanceID); err != nil {
101 if errors.Is(err, drivers.ErrNotFound) {
102 http.Error(w, "instance not found", http.StatusNotFound)
103 return
104 }
105 http.Error(w, "controller is not open", http.StatusConflict)
106 return
107 }
108
109 // Start goroutines for each event type.
110 grp, ctx := errgroup.WithContext(req.Context())

Callers

nothing calls this directly

Calls 14

WatchFilesMethod · 0.95
WatchResourcesMethod · 0.95
WatchLogsMethod · 0.95
AddRequestAttributesFunction · 0.92
recoverFunction · 0.85
serveSSEUntilCloseFunction · 0.85
ControllerMethod · 0.80
MessageMethod · 0.80
QueryMethod · 0.65
GetMethod · 0.65
ContextMethod · 0.65
StringMethod · 0.65

Tested by

no test coverage detected