@@ -815,10 +815,13 @@ func (api *API) workspaceAgentListeningPorts(rw http.ResponseWriter, r *http.Req
815
815
// @Router /workspaceagents/{workspaceagent}/containers/watch [get]
816
816
func (api * API )watchWorkspaceAgentContainers (rw http.ResponseWriter ,r * http.Request ) {
817
817
var (
818
- ctx = r .Context ()
819
818
workspaceAgent = httpmw .WorkspaceAgentParam (r )
819
+ logger = api .Logger .Named ("agent_container_watcher" ).With (slog .F ("agent_id" ,workspaceAgent .ID ))
820
820
)
821
821
822
+ ctx ,cancelCtx := context .WithCancel (r .Context ())
823
+ defer cancelCtx ()
824
+
822
825
// If the agent is unreachable, the request will hang. Assume that if we
823
826
// don't get a response after 30s that the agent is unreachable.
824
827
dialCtx ,cancel := context .WithTimeout (ctx ,30 * time .Second )
@@ -857,8 +860,7 @@ func (api *API) watchWorkspaceAgentContainers(rw http.ResponseWriter, r *http.Re
857
860
}
858
861
defer release ()
859
862
860
- watcherLogger := api .Logger .Named ("agent_container_watcher" ).With (slog .F ("agent_id" ,workspaceAgent .ID ))
861
- containersCh ,closer ,err := agentConn .WatchContainers (ctx ,watcherLogger )
863
+ containersCh ,closer ,err := agentConn .WatchContainers (ctx ,logger )
862
864
if err != nil {
863
865
httpapi .Write (ctx ,rw ,http .StatusInternalServerError , codersdk.Response {
864
866
Message :"Internal error watching agent's containers." ,
@@ -881,11 +883,11 @@ func (api *API) watchWorkspaceAgentContainers(rw http.ResponseWriter, r *http.Re
881
883
// close frames.
882
884
_ = conn .CloseRead (context .Background ())
883
885
886
+ go httpapi .HeartbeatClose (ctx ,logger ,cancelCtx ,conn )
887
+
884
888
ctx ,wsNetConn := codersdk .WebsocketNetConn (ctx ,conn ,websocket .MessageText )
885
889
defer wsNetConn .Close ()
886
890
887
- go httpapi .Heartbeat (ctx ,conn )
888
-
889
891
encoder := json .NewEncoder (wsNetConn )
890
892
891
893
for {