fix: exclude provisioner_state from workspace_build_with_user view (#22159)

The provisioner state for a workspace build was being loaded for every
long-lived agent rpc connection. Since this state can be anywhere from
kilobytes to megabytes this can gradually cause the `coderd` memory
footprint to grow over time. It's also a lot of unnecessary allocations
for every query that fetches a workspace build since only a few callers
ever actually reference the provisioner state.

This PR removes it from the returned workspace build and adds a query to
fetch the provisioner state explicitly.
This commit is contained in:
Jon Ayers
2026-02-23 22:46:17 -06:00
committed by GitHub
parent bf076fb7ee
commit 0a7a3da178
27 changed files with 379 additions and 90 deletions
+7 -15
View File
@@ -856,32 +856,24 @@ func (api *API) workspaceBuildLogs(rw http.ResponseWriter, r *http.Request) {
func (api *API) workspaceBuildState(rw http.ResponseWriter, r *http.Request) {
ctx := r.Context()
workspaceBuild := httpmw.WorkspaceBuildParam(r)
workspace, err := api.Database.GetWorkspaceByID(ctx, workspaceBuild.WorkspaceID)
if err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Message: "No workspace exists for this job.",
})
// The dbauthz layer enforces policy.ActionUpdate on the template.
row, err := api.Database.GetWorkspaceBuildProvisionerStateByID(ctx, workspaceBuild.ID)
if httpapi.Is404Error(err) {
httpapi.ResourceNotFound(rw)
return
}
template, err := api.Database.GetTemplateByID(ctx, workspace.TemplateID)
if err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Message: "Failed to get template",
Message: "Internal error fetching provisioner state.",
Detail: err.Error(),
})
return
}
// You must have update permissions on the template to get the state.
// This matches a push!
if !api.Authorize(r, policy.ActionUpdate, template.RBACObject()) {
httpapi.ResourceNotFound(rw)
return
}
rw.Header().Set("Content-Type", "application/json")
rw.WriteHeader(http.StatusOK)
_, _ = rw.Write(workspaceBuild.ProvisionerState)
_, _ = rw.Write(row.ProvisionerState)
}
// @Summary Update workspace build state