Skip to content

Commit 6960d19

Browse files
authored
feat: add provisioning timings to understand slow build times (#14274)
1 parent 9c8c6a9 commit 6960d19

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+2653
-701
lines changed

coderd/database/dbauthz/dbauthz.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2793,6 +2793,14 @@ func (q *querier) InsertProvisionerJobLogs(ctx context.Context, arg database.Ins
27932793
return q.db.InsertProvisionerJobLogs(ctx, arg)
27942794
}
27952795

2796+
// TODO: We need to create a ProvisionerJob resource type
2797+
func (q *querier) InsertProvisionerJobTimings(ctx context.Context, arg database.InsertProvisionerJobTimingsParams) ([]database.ProvisionerJobTiming, error) {
2798+
// if err := q.authorizeContext(ctx, policy.ActionCreate, rbac.ResourceSystem); err != nil {
2799+
// return nil, err
2800+
// }
2801+
return q.db.InsertProvisionerJobTimings(ctx, arg)
2802+
}
2803+
27962804
func (q *querier) InsertProvisionerKey(ctx context.Context, arg database.InsertProvisionerKeyParams) (database.ProvisionerKey, error) {
27972805
return insert(q.log, q.auth, rbac.ResourceProvisionerKeys.InOrg(arg.OrganizationID).WithID(arg.ID), q.db.InsertProvisionerKey)(ctx, arg)
27982806
}

coderd/database/dbauthz/dbauthz_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2470,6 +2470,13 @@ func (s *MethodTestSuite) TestSystemFunctions() {
24702470
JobID: j.ID,
24712471
}).Asserts( /*rbac.ResourceSystem, policy.ActionCreate*/ )
24722472
}))
2473+
s.Run("InsertProvisionerJobTimings", s.Subtest(func(db database.Store, check *expects) {
2474+
// TODO: we need to create a ProvisionerJob resource
2475+
j := dbgen.ProvisionerJob(s.T(), db, nil, database.ProvisionerJob{})
2476+
check.Args(database.InsertProvisionerJobTimingsParams{
2477+
JobID: j.ID,
2478+
}).Asserts( /*rbac.ResourceSystem, policy.ActionCreate*/ )
2479+
}))
24732480
s.Run("UpsertProvisionerDaemon", s.Subtest(func(db database.Store, check *expects) {
24742481
org := dbgen.Organization(s.T(), db, database.Organization{})
24752482
pd := rbac.ResourceProvisionerDaemon.InOrg(org.ID)

coderd/database/dbmem/dbmem.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6652,6 +6652,15 @@ func (q *FakeQuerier) InsertProvisionerJobLogs(_ context.Context, arg database.I
66526652
return logs, nil
66536653
}
66546654

6655+
func (*FakeQuerier) InsertProvisionerJobTimings(_ context.Context, arg database.InsertProvisionerJobTimingsParams) ([]database.ProvisionerJobTiming, error) {
6656+
err := validateDatabaseType(arg)
6657+
if err != nil {
6658+
return nil, err
6659+
}
6660+
6661+
return nil, nil
6662+
}
6663+
66556664
func (q *FakeQuerier) InsertProvisionerKey(_ context.Context, arg database.InsertProvisionerKeyParams) (database.ProvisionerKey, error) {
66566665
err := validateDatabaseType(arg)
66576666
if err != nil {

coderd/database/dbmetrics/dbmetrics.go

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/dbmock/dbmock.go

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/dbtime/dbtime.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ func Now() time.Time {
99

1010
// Time returns a time compatible with Postgres. Postgres only stores dates with
1111
// microsecond precision.
12+
// FIXME(dannyk): refactor all calls to Time() to expect the input time to be modified to UTC; there are currently a
13+
//
14+
// few calls whose behavior would change subtly.
15+
// See https://github.com/coder/coder/pull/14274#discussion_r1718427461
1216
func Time(t time.Time) time.Time {
1317
return t.Round(time.Microsecond)
1418
}

coderd/database/dump.sql

Lines changed: 89 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/foreign_key_constraint.go

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
DROP VIEW IF EXISTS provisioner_job_stats;
2+
3+
DROP TYPE IF EXISTS provisioner_job_timing_stage CASCADE;
4+
5+
DROP TABLE IF EXISTS provisioner_job_timings;
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
CREATE TYPE provisioner_job_timing_stage AS ENUM (
2+
'init',
3+
'plan',
4+
'graph',
5+
'apply'
6+
);
7+
8+
CREATE TABLE provisioner_job_timings
9+
(
10+
job_id uuid NOT NULL REFERENCES provisioner_jobs (id) ON DELETE CASCADE,
11+
started_at timestamp with time zone not null,
12+
ended_at timestamp with time zone not null,
13+
stage provisioner_job_timing_stage not null,
14+
source text not null,
15+
action text not null,
16+
resource text not null
17+
);
18+
19+
CREATE VIEW provisioner_job_stats AS
20+
SELECT pj.id AS job_id,
21+
pj.job_status,
22+
wb.workspace_id,
23+
pj.worker_id,
24+
pj.error,
25+
pj.error_code,
26+
pj.updated_at,
27+
GREATEST(EXTRACT(EPOCH FROM (pj.started_at - pj.created_at)), 0) AS queued_secs,
28+
GREATEST(EXTRACT(EPOCH FROM (pj.completed_at - pj.started_at)), 0) AS completion_secs,
29+
GREATEST(EXTRACT(EPOCH FROM (pj.canceled_at - pj.started_at)), 0) AS canceled_secs,
30+
GREATEST(EXTRACT(EPOCH FROM (
31+
MAX(CASE WHEN pjt.stage = 'init'::provisioner_job_timing_stage THEN pjt.ended_at END) -
32+
MIN(CASE WHEN pjt.stage = 'init'::provisioner_job_timing_stage THEN pjt.started_at END))), 0) AS init_secs,
33+
GREATEST(EXTRACT(EPOCH FROM (
34+
MAX(CASE WHEN pjt.stage = 'plan'::provisioner_job_timing_stage THEN pjt.ended_at END) -
35+
MIN(CASE WHEN pjt.stage = 'plan'::provisioner_job_timing_stage THEN pjt.started_at END))), 0) AS plan_secs,
36+
GREATEST(EXTRACT(EPOCH FROM (
37+
MAX(CASE WHEN pjt.stage = 'graph'::provisioner_job_timing_stage THEN pjt.ended_at END) -
38+
MIN(CASE WHEN pjt.stage = 'graph'::provisioner_job_timing_stage THEN pjt.started_at END))), 0) AS graph_secs,
39+
GREATEST(EXTRACT(EPOCH FROM (
40+
MAX(CASE WHEN pjt.stage = 'apply'::provisioner_job_timing_stage THEN pjt.ended_at END) -
41+
MIN(CASE WHEN pjt.stage = 'apply'::provisioner_job_timing_stage THEN pjt.started_at END))), 0) AS apply_secs
42+
FROM provisioner_jobs pj
43+
JOIN workspace_builds wb ON wb.job_id = pj.id
44+
LEFT JOIN provisioner_job_timings pjt ON pjt.job_id = pj.id
45+
GROUP BY pj.id, wb.workspace_id;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy