fix(coderd): bump workspace autostop deadline on chat heartbeat (#23314)

- Wire `workspacestats.ActivityBumpWorkspace` into `trackWorkspaceUsage`
so the workspace build deadline is extended each time the chat heartbeat
fires
- Prevents mid-conversation autostop for chat workspaces
- Updates `TestHeartbeatBumpsWorkspaceUsage` verifying the deadline bump

> This PR was created with the help of Coder Agents, and was reviewed by two humans and their pet robots 🧑‍💻🤝🤖
This commit is contained in:
Cian Johnston
2026-03-19 22:07:20 +00:00
committed by GitHub
parent 7c3c7bb5e6
commit 2f50e89afd
4 changed files with 101 additions and 24 deletions
+22 -5
View File
@@ -2351,11 +2351,12 @@ func (p *Server) tryAutoPromoteQueuedMessage(
}
// trackWorkspaceUsage bumps the workspace's last_used_at via the
// usage tracker. If wsID is not yet valid, it re-reads the chat
// from the DB to pick up late associations (e.g. create_workspace
// linking a workspace mid-conversation). The caller should store
// the returned value so that subsequent calls skip the DB lookup
// once a workspace has been found.
// usage tracker and extends the workspace's autostop deadline. If
// wsID is not yet valid, it re-reads the chat from the DB to pick
// up late associations (e.g. create_workspace linking a workspace
// mid-conversation). The caller should store the returned value so
// that subsequent calls skip the DB lookup once a workspace has
// been found.
func (p *Server) trackWorkspaceUsage(
ctx context.Context,
chatID uuid.UUID,
@@ -2375,6 +2376,22 @@ func (p *Server) trackWorkspaceUsage(
}
if wsID.Valid {
p.usageTracker.Add(wsID.UUID)
// Bump the workspace autostop deadline. We pass time.Time{}
// for nextAutostart since we don't have access to
// TemplateScheduleStore here. The activity bump logic
// defaults to the template's activity_bump duration
// (typically 1 hour). Chat workspaces are never prebuilds,
// so no prebuild guard is needed (unlike reporter.go).
//
// This fires every heartbeat (~30s) but the SQL only
// writes when 5% of the deadline has elapsed — most calls
// perform a read-only CTE lookup with no UPDATE.
//
// Scaling note: for 10,000 active chats, this could lead to
// approx. 333 CTE queries/second. A cheap fix for this could
// be to heartbeat every Nth query. Leaving as potential future
// low-hanging fruit if needed.
workspacestats.ActivityBumpWorkspace(ctx, logger.Named("activity_bump"), p.db, wsID.UUID, time.Time{})
}
return wsID
}