feat(coderd): add queue-position-free provisioner job query - #28367
Conversation
| // Fetches provisioner jobs by their IDs without computing queue position or | ||
| // queue size. Callers that do not need the queue position should prefer this | ||
| // over GetProvisionerJobsByIDsWithQueuePosition, whose window functions over | ||
| // pending jobs and provisioner daemons are comparatively expensive. |
There was a problem hiding this comment.
nit: I don't think having a comment here (at least not one this long) is really necessary
| jobs := make([]database.GetProvisionerJobsByIDsWithQueuePositionRow, 0, len(provisionerJobs)) | ||
| for _, job := range provisionerJobs { | ||
| jobs = append(jobs, database.GetProvisionerJobsByIDsWithQueuePositionRow{ | ||
| ID: job.ID, | ||
| CreatedAt: job.CreatedAt, | ||
| ProvisionerJob: job, | ||
| }) | ||
| } |
There was a problem hiding this comment.
I imagine there's not a nice way to do it, and we'll probably clean things up at their call sites in a follow up PR anyways, but it would be nice if we had a way to have Database.GetProvisionerJobsByIDs to return database.GetProvisionerJobsByIDsWithQueuePositionRow directly so we didn't have to do additional allocations inline here.
There was a problem hiding this comment.
Yeah, the methods and their return types are autogenerated by sqlc, so I think it would be hard.
Fortunately these are not pointer types, so we get one allocation for the slice and we're good to go.
Follow-up to #28302 (GRU-82, RFC). That PR added related-data selection but noted that selecting
latest_build.jobstill ran the expensiveGetProvisionerJobsByIDsWithQueuePositionquery, which computes queue position and size with window functions over pending jobs and provisioner daemons and is consistently the top resource consumer in scale tests.This PR adds a cheaper
GetProvisionerJobsByIDsquery that fetches jobs by ID without the queue-position computation, and selects between the two based on whetherlatest_build.job.queue_positionis requested. When the queue position is not selected,QueuePositionandQueueSizeare left zero and the rest of the response is unchanged.Both paths go through a single
provisionerJobsByIDsAPI method that takes thejobRelatedselection, switches on it, and reshapes the cheaper query's rows intoGetProvisionerJobsByIDsWithQueuePositionRowso downstream conversion is uniform.The new query has the same dbauthz properties as the queue-position variant (system-level pass-through pending the proper provisioner-job RBAC check tracked in #16160), with a matching authorization test.
No behavior change for existing callers: they select
queue_position(viaallLatestBuildRelated), so they continue to use the queue-position query.Generated by Coder Agents on behalf of @spikecurtis.