MCPcopy Index your code
hub / github.com/coder/coder / handleWatch

Method handleWatch

agent/agentgit/api.go:41–164  ·  view source on GitHub ↗
(rw http.ResponseWriter, r *http.Request)

Source from the content-addressed store, hash-verified

39}
40
41func (a *API) handleWatch(rw http.ResponseWriter, r *http.Request) {
42 ctx := r.Context()
43
44 var watchChatID uuid.UUID
45 var hasWatchChatID bool
46 if chatIDStr := r.URL.Query().Get("chat_id"); chatIDStr != "" {
47 if parsedChatID, parseErr := uuid.Parse(chatIDStr); parseErr == nil {
48 watchChatID = parsedChatID
49 hasWatchChatID = true
50
51 // Reuse header-derived ancestors only when the query chat
52 // matches the header chat. Otherwise the ancestors belong
53 // to a different chat and would be misleading in logs.
54 var ancestors []uuid.UUID
55 if chatContext, ok := agentchat.FromContext(ctx); ok && chatContext.ID == watchChatID {
56 ancestors = chatContext.AncestorIDs
57 }
58 ctx = agentchat.WithContext(ctx, watchChatID, ancestors)
59 }
60 }
61 logger := a.logger.With(agentchat.Fields(ctx)...)
62
63 conn, err := websocket.Accept(rw, r, &websocket.AcceptOptions{
64 CompressionMode: websocket.CompressionNoContextTakeover,
65 })
66 if err != nil {
67 httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
68 Message: "Failed to accept WebSocket.",
69 Detail: err.Error(),
70 })
71 return
72 }
73
74 // 4 MiB read limit — subscribe messages with many paths can exceed the
75 // default 32 KB limit. Matches the SDK/proxy side.
76 conn.SetReadLimit(1 << 22)
77
78 stream := wsjson.NewStream[
79 codersdk.WorkspaceAgentGitClientMessage,
80 codersdk.WorkspaceAgentGitServerMessage,
81 ](conn, websocket.MessageText, websocket.MessageText, logger)
82
83 ctx, cancel := context.WithCancel(ctx)
84 defer cancel()
85
86 go httpapi.HeartbeatClose(ctx, logger, cancel, conn)
87
88 handler := NewHandler(logger, a.opts...)
89
90 // Scan returns nil only when no roots are subscribed; once any
91 // root lands it returns either a delta or a heartbeat message.
92 scanAndSend := func() {
93 msg := handler.Scan(ctx)
94 if msg == nil {
95 return
96 }
97 if err := stream.Send(*msg); err != nil {
98 logger.Debug(ctx, "failed to send changes", slog.Error(err))

Callers

nothing calls this directly

Calls 15

ScanMethod · 0.95
SubscribeMethod · 0.95
RequestScanMethod · 0.95
RunLoopMethod · 0.95
FromContextFunction · 0.92
WithContextFunction · 0.92
FieldsFunction · 0.92
WriteFunction · 0.92
NewStreamFunction · 0.92
HeartbeatCloseFunction · 0.92
NewHandlerFunction · 0.85
unsubscribeFunction · 0.85

Tested by

no test coverage detected