Skip to content

Commit 69f911d

Browse files
authored
feat: add queue_position and queue_size to provisioner jobs (#8074)
1 parent bbb0fab commit 69f911d

26 files changed

+417
-75
lines changed

.github/workflows/ci.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ jobs:
153153

154154
- name: Install sqlc
155155
run: |
156-
curl -sSL https://github.com/kyleconroy/sqlc/releases/download/v1.17.2/sqlc_1.17.2_linux_amd64.tar.gz | sudo tar -C /usr/bin -xz sqlc
156+
curl -sSL https://github.com/kyleconroy/sqlc/releases/download/v1.18.0/sqlc_1.18.0_linux_amd64.tar.gz | sudo tar -C /usr/bin -xz sqlc
157157
158158
- name: go install tools
159159
run: |

cli/testdata/coder_list_--output_json.golden

+3-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@
3535
"file_id": "[workspace build file ID]",
3636
"tags": {
3737
"scope": "organization"
38-
}
38+
},
39+
"queue_position": 0,
40+
"queue_size": 0
3941
},
4042
"reason": "initiator",
4143
"resources": [],

coderd/apidoc/docs.go

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/apidoc/swagger.json

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/dbauthz/dbauthz.go

+5
Original file line numberDiff line numberDiff line change
@@ -1087,6 +1087,11 @@ func (q *querier) GetProvisionerJobsByIDs(ctx context.Context, ids []uuid.UUID)
10871087
return q.db.GetProvisionerJobsByIDs(ctx, ids)
10881088
}
10891089

1090+
// TODO: we need to add a provisioner job resource
1091+
func (q *querier) GetProvisionerJobsByIDsWithQueuePosition(ctx context.Context, ids []uuid.UUID) ([]database.GetProvisionerJobsByIDsWithQueuePositionRow, error) {
1092+
return q.db.GetProvisionerJobsByIDsWithQueuePosition(ctx, ids)
1093+
}
1094+
10901095
// TODO: We need to create a ProvisionerJob resource type
10911096
func (q *querier) GetProvisionerJobsCreatedAfter(ctx context.Context, createdAt time.Time) ([]database.ProvisionerJob, error) {
10921097
// if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {

coderd/database/dbfake/dbfake.go

+32
Original file line numberDiff line numberDiff line change
@@ -2051,6 +2051,38 @@ func (q *fakeQuerier) GetProvisionerJobsByIDs(_ context.Context, ids []uuid.UUID
20512051
return jobs, nil
20522052
}
20532053

2054+
func (q *fakeQuerier) GetProvisionerJobsByIDsWithQueuePosition(_ context.Context, ids []uuid.UUID) ([]database.GetProvisionerJobsByIDsWithQueuePositionRow, error) {
2055+
q.mutex.RLock()
2056+
defer q.mutex.RUnlock()
2057+
2058+
jobs := make([]database.GetProvisionerJobsByIDsWithQueuePositionRow, 0)
2059+
queuePosition := int64(1)
2060+
for _, job := range q.provisionerJobs {
2061+
for _, id := range ids {
2062+
if id == job.ID {
2063+
job := database.GetProvisionerJobsByIDsWithQueuePositionRow{
2064+
ProvisionerJob: job,
2065+
}
2066+
if !job.ProvisionerJob.StartedAt.Valid {
2067+
job.QueuePosition = queuePosition
2068+
}
2069+
jobs = append(jobs, job)
2070+
break
2071+
}
2072+
}
2073+
if !job.StartedAt.Valid {
2074+
queuePosition++
2075+
}
2076+
}
2077+
for _, job := range jobs {
2078+
if !job.ProvisionerJob.StartedAt.Valid {
2079+
// Set it to the max position!
2080+
job.QueueSize = queuePosition
2081+
}
2082+
}
2083+
return jobs, nil
2084+
}
2085+
20542086
func (q *fakeQuerier) GetProvisionerJobsCreatedAfter(_ context.Context, after time.Time) ([]database.ProvisionerJob, error) {
20552087
q.mutex.RLock()
20562088
defer q.mutex.RUnlock()

coderd/database/dbmetrics/dbmetrics.go

+7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/dbmock/dbmock.go

+15
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/models.go

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/querier.go

+2-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/querier_test.go

+75
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ package database_test
55
import (
66
"context"
77
"database/sql"
8+
"encoding/json"
9+
"sort"
810
"testing"
911
"time"
1012

@@ -312,3 +314,76 @@ func TestDefaultProxy(t *testing.T) {
312314
require.NoError(t, err, "get deployment id")
313315
require.Equal(t, depID, found)
314316
}
317+
318+
func TestQueuePosition(t *testing.T) {
319+
t.Parallel()
320+
321+
if testing.Short() {
322+
t.SkipNow()
323+
}
324+
sqlDB := testSQLDB(t)
325+
err := migrations.Up(sqlDB)
326+
require.NoError(t, err)
327+
db := database.New(sqlDB)
328+
ctx := testutil.Context(t, testutil.WaitLong)
329+
330+
org := dbgen.Organization(t, db, database.Organization{})
331+
jobCount := 10
332+
jobs := []database.ProvisionerJob{}
333+
jobIDs := []uuid.UUID{}
334+
for i := 0; i < jobCount; i++ {
335+
job := dbgen.ProvisionerJob(t, db, database.ProvisionerJob{
336+
OrganizationID: org.ID,
337+
Tags: database.StringMap{},
338+
})
339+
jobs = append(jobs, job)
340+
jobIDs = append(jobIDs, job.ID)
341+
342+
// We need a slight amount of time between each insertion to ensure that
343+
// the queue position is correct... it's sorted by `created_at`.
344+
time.Sleep(time.Millisecond)
345+
}
346+
347+
queued, err := db.GetProvisionerJobsByIDsWithQueuePosition(ctx, jobIDs)
348+
require.NoError(t, err)
349+
require.Len(t, queued, jobCount)
350+
sort.Slice(queued, func(i, j int) bool {
351+
return queued[i].QueuePosition < queued[j].QueuePosition
352+
})
353+
// Ensure that the queue positions are correct based on insertion ID!
354+
for index, job := range queued {
355+
require.Equal(t, job.QueuePosition, int64(index+1))
356+
require.Equal(t, job.ProvisionerJob.ID, jobs[index].ID)
357+
}
358+
359+
job, err := db.AcquireProvisionerJob(ctx, database.AcquireProvisionerJobParams{
360+
StartedAt: sql.NullTime{
361+
Time: database.Now(),
362+
Valid: true,
363+
},
364+
Types: database.AllProvisionerTypeValues(),
365+
WorkerID: uuid.NullUUID{
366+
UUID: uuid.New(),
367+
Valid: true,
368+
},
369+
Tags: json.RawMessage("{}"),
370+
})
371+
require.NoError(t, err)
372+
require.Equal(t, jobs[0].ID, job.ID)
373+
374+
queued, err = db.GetProvisionerJobsByIDsWithQueuePosition(ctx, jobIDs)
375+
require.NoError(t, err)
376+
require.Len(t, queued, jobCount)
377+
sort.Slice(queued, func(i, j int) bool {
378+
return queued[i].QueuePosition < queued[j].QueuePosition
379+
})
380+
// Ensure that queue positions are updated now that the first job has been acquired!
381+
for index, job := range queued {
382+
if index == 0 {
383+
require.Equal(t, job.QueuePosition, int64(0))
384+
continue
385+
}
386+
require.Equal(t, job.QueuePosition, int64(index))
387+
require.Equal(t, job.ProvisionerJob.ID, jobs[index].ID)
388+
}
389+
}

coderd/database/queries.sql.go

+84-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries/provisionerjobs.sql

+32
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,38 @@ FROM
4747
WHERE
4848
id = ANY(@ids :: uuid [ ]);
4949

50+
-- name: GetProvisionerJobsByIDsWithQueuePosition :many
51+
WITH unstarted_jobs AS (
52+
SELECT
53+
id, created_at
54+
FROM
55+
provisioner_jobs
56+
WHERE
57+
started_at IS NULL
58+
),
59+
queue_position AS (
60+
SELECT
61+
id,
62+
ROW_NUMBER() OVER (ORDER BY created_at ASC) AS queue_position
63+
FROM
64+
unstarted_jobs
65+
),
66+
queue_size AS (
67+
SELECT COUNT(*) as count FROM unstarted_jobs
68+
)
69+
SELECT
70+
sqlc.embed(pj),
71+
COALESCE(qp.queue_position, 0) AS queue_position,
72+
COALESCE(qs.count, 0) AS queue_size
73+
FROM
74+
provisioner_jobs pj
75+
LEFT JOIN
76+
queue_position qp ON qp.id = pj.id
77+
LEFT JOIN
78+
queue_size qs ON TRUE
79+
WHERE
80+
pj.id = ANY(@ids :: uuid [ ]);
81+
5082
-- name: GetProvisionerJobsCreatedAfter :many
5183
SELECT * FROM provisioner_jobs WHERE created_at > $1;
5284

0 commit comments

Comments
 (0)