2021-05-06 14:54:10 -07:00
|
|
|
|
// Copyright (c) HashiCorp, Inc.
|
|
|
|
|
|
// SPDX-License-Identifier: BUSL-1.1
|
2023-02-02 17:15:17 -08:00
|
|
|
|
|
2021-05-06 14:54:10 -07:00
|
|
|
|
package scheduler
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
|
"context"
|
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
|
|
"github.com/hashicorp/boundary/internal/errors"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// Job defines an interface for jobs that can be invoked by the scheduler.
|
2024-09-19 15:21:48 -04:00
|
|
|
|
// Multiple goroutines may invoke methods on a Job simultaneously.
|
2021-05-06 14:54:10 -07:00
|
|
|
|
type Job interface {
|
2024-09-19 15:21:48 -04:00
|
|
|
|
// Status reports the job’s current status. It is called periodically
|
|
|
|
|
|
// while the Run method is running and immediately after the Run method
|
|
|
|
|
|
// completes.
|
|
|
|
|
|
//
|
|
|
|
|
|
// The scheduler uses the values in the returned JobStatus to verify
|
|
|
|
|
|
// that progress is being made by the job. The scheduler will interrupt
|
|
|
|
|
|
// the job if the values returned by Status do not change over a
|
|
|
|
|
|
// configurable amount of time.
|
|
|
|
|
|
//
|
|
|
|
|
|
// See scheduler.WithInterruptThreshold for more information.
|
2021-05-06 14:54:10 -07:00
|
|
|
|
Status() JobStatus
|
|
|
|
|
|
|
2024-09-19 15:21:48 -04:00
|
|
|
|
// Run starts the specified job and waits for it to complete.
|
|
|
|
|
|
//
|
2024-09-20 12:14:29 -04:00
|
|
|
|
// The context parameter is used to notify the job that it should exit.
|
|
|
|
|
|
//
|
|
|
|
|
|
// The statusThreshold parameter is the amount of time the job has to
|
|
|
|
|
|
// return a JobStatus with values different from the previous
|
|
|
|
|
|
// JobStatus. Each time a JobStatus with values different from the
|
|
|
|
|
|
// previous JobStatus is returned, the timer for the threshold
|
|
|
|
|
|
// restarts. If the threshold is reached, the context is canceled.
|
|
|
|
|
|
//
|
|
|
|
|
|
// If the returned error is not nil, the job will be scheduled to run
|
|
|
|
|
|
// again immediately and the returned error will be logged.
|
|
|
|
|
|
Run(ctx context.Context, statusThreshold time.Duration) error
|
2021-05-06 14:54:10 -07:00
|
|
|
|
|
2024-09-19 15:21:48 -04:00
|
|
|
|
// NextRunIn returns the duration the job scheduler should wait before
|
|
|
|
|
|
// running the job again. It is only called after the Run method has
|
|
|
|
|
|
// completed and returned a nil error. If a zero duration is returned
|
2021-06-11 11:36:14 -07:00
|
|
|
|
// the job will be scheduled to run again immediately.
|
2024-09-19 15:21:48 -04:00
|
|
|
|
//
|
|
|
|
|
|
// If an error is returned, the error will be logged but the returned
|
|
|
|
|
|
// duration will still be used in scheduling.
|
2022-01-05 14:38:38 -05:00
|
|
|
|
NextRunIn(context.Context) (time.Duration, error)
|
2021-05-06 14:54:10 -07:00
|
|
|
|
|
2021-06-11 11:36:14 -07:00
|
|
|
|
// Name is the unique name of the job.
|
2021-05-06 14:54:10 -07:00
|
|
|
|
Name() string
|
|
|
|
|
|
|
|
|
|
|
|
// Description is the human readable description of the job.
|
|
|
|
|
|
Description() string
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-09-19 15:21:48 -04:00
|
|
|
|
// A JobStatus represents the status of a job.
|
|
|
|
|
|
// Completed and Total are used to indicate job progress.
|
|
|
|
|
|
// The Completed value cannot be greater than the Total value
|
|
|
|
|
|
// and both values must be greater than or equal to zero.
|
|
|
|
|
|
//
|
2024-09-24 09:27:24 -04:00
|
|
|
|
// Retries is used to indicate how many times the job has retried
|
|
|
|
|
|
// accomplishing work. The value must be greater than or equal to zero.
|
|
|
|
|
|
//
|
2024-09-19 15:21:48 -04:00
|
|
|
|
// The scheduler uses the values in the JobStatus to verify that
|
|
|
|
|
|
// progress is being made by the job. The scheduler will interrupt the job
|
|
|
|
|
|
// if the values returned by Status do not change over a configurable
|
|
|
|
|
|
// amount of time.
|
2021-05-06 14:54:10 -07:00
|
|
|
|
type JobStatus struct {
|
2024-09-19 15:21:48 -04:00
|
|
|
|
// The job's work items
|
|
|
|
|
|
Completed int // number of items processed
|
|
|
|
|
|
Total int // total number of items to be processed
|
2024-09-24 09:27:24 -04:00
|
|
|
|
|
|
|
|
|
|
// The job's liveliness
|
|
|
|
|
|
Retries int // number of times the job has retried work
|
2021-05-06 14:54:10 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-06-06 17:09:08 -04:00
|
|
|
|
func validateJob(ctx context.Context, j Job) error {
|
2021-05-06 14:54:10 -07:00
|
|
|
|
const op = "scheduler.validateJob"
|
|
|
|
|
|
if j == nil {
|
2023-06-06 17:09:08 -04:00
|
|
|
|
return errors.New(ctx, errors.InvalidParameter, op, "missing job")
|
2021-05-06 14:54:10 -07:00
|
|
|
|
}
|
|
|
|
|
|
if j.Name() == "" {
|
2023-06-06 17:09:08 -04:00
|
|
|
|
return errors.New(ctx, errors.InvalidParameter, op, "missing name")
|
2021-05-06 14:54:10 -07:00
|
|
|
|
}
|
|
|
|
|
|
if j.Description() == "" {
|
2023-06-06 17:09:08 -04:00
|
|
|
|
return errors.New(ctx, errors.InvalidParameter, op, "missing description")
|
2021-05-06 14:54:10 -07:00
|
|
|
|
}
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|