refactor(coderd/provisionerdserver): use quartz.Clock instead of TimeNowFn (#15642)

Replace `TimeNowFn` in `provisionerdserver` with `quartz.Clock` as
well as pass `coderd`'s `Clock` to `provisionerdserver`.
This commit is contained in:
Danielle Maywood
2024-11-25 16:25:36 +00:00
committed by GitHub
parent bbc549d2df
commit 0896f339c4
4 changed files with 36 additions and 32 deletions
+25 -23
View File
@@ -46,6 +46,7 @@ import (
"github.com/coder/coder/v2/provisionerd/proto"
"github.com/coder/coder/v2/provisionersdk"
sdkproto "github.com/coder/coder/v2/provisionersdk/proto"
"github.com/coder/quartz"
)
const (
@@ -61,8 +62,9 @@ const (
type Options struct {
OIDCConfig promoauth.OAuth2Config
ExternalAuthConfigs []*externalauth.Config
// TimeNowFn is only used in tests
TimeNowFn func() time.Time
// Clock for testing
Clock quartz.Clock
// AcquireJobLongPollDur is used in tests
AcquireJobLongPollDur time.Duration
@@ -104,7 +106,7 @@ type server struct {
OIDCConfig promoauth.OAuth2Config
TimeNowFn func() time.Time
Clock quartz.Clock
acquireJobLongPollDur time.Duration
@@ -191,6 +193,9 @@ func NewServer(
if options.HeartbeatInterval == 0 {
options.HeartbeatInterval = DefaultHeartbeatInterval
}
if options.Clock == nil {
options.Clock = quartz.NewReal()
}
s := &server{
lifecycleCtx: lifecycleCtx,
@@ -213,7 +218,7 @@ func NewServer(
UserQuietHoursScheduleStore: userQuietHoursScheduleStore,
DeploymentValues: deploymentValues,
OIDCConfig: options.OIDCConfig,
TimeNowFn: options.TimeNowFn,
Clock: options.Clock,
acquireJobLongPollDur: options.AcquireJobLongPollDur,
heartbeatInterval: options.HeartbeatInterval,
heartbeatFn: options.HeartbeatFn,
@@ -229,11 +234,8 @@ func NewServer(
// timeNow should be used when trying to get the current time for math
// calculations regarding workspace start and stop time.
func (s *server) timeNow() time.Time {
if s.TimeNowFn != nil {
return dbtime.Time(s.TimeNowFn())
}
return dbtime.Now()
func (s *server) timeNow(tags ...string) time.Time {
return dbtime.Time(s.Clock.Now(tags...))
}
// heartbeatLoop runs heartbeatOnce at the interval specified by HeartbeatInterval
@@ -365,7 +367,7 @@ func (s *server) AcquireJobWithCancel(stream proto.DRPCProvisionerDaemon_Acquire
logger.Error(streamCtx, "recv error and failed to cancel acquire job", slog.Error(recvErr))
// Well, this is awkward. We hit an error receiving from the stream, but didn't cancel before we locked a job
// in the database. We need to mark this job as failed so the end user can retry if they want to.
now := dbtime.Now()
now := s.timeNow()
err := s.Database.UpdateProvisionerJobWithCompleteByID(
//nolint:gocritic // Provisionerd has specific authz rules.
dbauthz.AsProvisionerd(context.Background()),
@@ -406,7 +408,7 @@ func (s *server) acquireProtoJob(ctx context.Context, job database.ProvisionerJo
err := s.Database.UpdateProvisionerJobWithCompleteByID(ctx, database.UpdateProvisionerJobWithCompleteByIDParams{
ID: job.ID,
CompletedAt: sql.NullTime{
Time: dbtime.Now(),
Time: s.timeNow(),
Valid: true,
},
Error: sql.NullString{
@@ -414,7 +416,7 @@ func (s *server) acquireProtoJob(ctx context.Context, job database.ProvisionerJo
Valid: true,
},
ErrorCode: job.ErrorCode,
UpdatedAt: dbtime.Now(),
UpdatedAt: s.timeNow(),
})
if err != nil {
return xerrors.Errorf("update provisioner job: %w", err)
@@ -792,7 +794,7 @@ func (s *server) UpdateJob(ctx context.Context, request *proto.UpdateJobRequest)
}
err = s.Database.UpdateProvisionerJobByID(ctx, database.UpdateProvisionerJobByIDParams{
ID: parsedID,
UpdatedAt: dbtime.Now(),
UpdatedAt: s.timeNow(),
})
if err != nil {
return nil, xerrors.Errorf("update job: %w", err)
@@ -869,7 +871,7 @@ func (s *server) UpdateJob(ctx context.Context, request *proto.UpdateJobRequest)
err := s.Database.UpdateTemplateVersionDescriptionByJobID(ctx, database.UpdateTemplateVersionDescriptionByJobIDParams{
JobID: job.ID,
Readme: string(request.Readme),
UpdatedAt: dbtime.Now(),
UpdatedAt: s.timeNow(),
})
if err != nil {
return nil, xerrors.Errorf("update template version description: %w", err)
@@ -958,7 +960,7 @@ func (s *server) FailJob(ctx context.Context, failJob *proto.FailedJob) (*proto.
return nil, xerrors.Errorf("job already completed")
}
job.CompletedAt = sql.NullTime{
Time: dbtime.Now(),
Time: s.timeNow(),
Valid: true,
}
job.Error = sql.NullString{
@@ -973,7 +975,7 @@ func (s *server) FailJob(ctx context.Context, failJob *proto.FailedJob) (*proto.
err = s.Database.UpdateProvisionerJobWithCompleteByID(ctx, database.UpdateProvisionerJobWithCompleteByIDParams{
ID: jobID,
CompletedAt: job.CompletedAt,
UpdatedAt: dbtime.Now(),
UpdatedAt: s.timeNow(),
Error: job.Error,
ErrorCode: job.ErrorCode,
})
@@ -1008,7 +1010,7 @@ func (s *server) FailJob(ctx context.Context, failJob *proto.FailedJob) (*proto.
if jobType.WorkspaceBuild.State != nil {
err = db.UpdateWorkspaceBuildProvisionerStateByID(ctx, database.UpdateWorkspaceBuildProvisionerStateByIDParams{
ID: input.WorkspaceBuildID,
UpdatedAt: dbtime.Now(),
UpdatedAt: s.timeNow(),
ProvisionerState: jobType.WorkspaceBuild.State,
})
if err != nil {
@@ -1016,7 +1018,7 @@ func (s *server) FailJob(ctx context.Context, failJob *proto.FailedJob) (*proto.
}
err = db.UpdateWorkspaceBuildDeadlineByID(ctx, database.UpdateWorkspaceBuildDeadlineByIDParams{
ID: input.WorkspaceBuildID,
UpdatedAt: dbtime.Now(),
UpdatedAt: s.timeNow(),
Deadline: build.Deadline,
MaxDeadline: build.MaxDeadline,
})
@@ -1382,7 +1384,7 @@ func (s *server) CompleteJob(ctx context.Context, completed *proto.CompletedJob)
err = s.Database.UpdateTemplateVersionExternalAuthProvidersByJobID(ctx, database.UpdateTemplateVersionExternalAuthProvidersByJobIDParams{
JobID: jobID,
ExternalAuthProviders: json.RawMessage(externalAuthProvidersMessage),
UpdatedAt: dbtime.Now(),
UpdatedAt: s.timeNow(),
})
if err != nil {
return nil, xerrors.Errorf("update template version external auth providers: %w", err)
@@ -1390,9 +1392,9 @@ func (s *server) CompleteJob(ctx context.Context, completed *proto.CompletedJob)
err = s.Database.UpdateProvisionerJobWithCompleteByID(ctx, database.UpdateProvisionerJobWithCompleteByIDParams{
ID: jobID,
UpdatedAt: dbtime.Now(),
UpdatedAt: s.timeNow(),
CompletedAt: sql.NullTime{
Time: dbtime.Now(),
Time: s.timeNow(),
Valid: true,
},
Error: completedError,
@@ -1687,9 +1689,9 @@ func (s *server) CompleteJob(ctx context.Context, completed *proto.CompletedJob)
err = s.Database.UpdateProvisionerJobWithCompleteByID(ctx, database.UpdateProvisionerJobWithCompleteByIDParams{
ID: jobID,
UpdatedAt: dbtime.Now(),
UpdatedAt: s.timeNow(),
CompletedAt: sql.NullTime{
Time: dbtime.Now(),
Time: s.timeNow(),
Valid: true,
},
Error: sql.NullString{},