This adds retries as an attribute to JobStatus allowing a job to indicate liveness to the scheduler when work has not progressed. A job could use this and the statusThreshold passed into the Run method to break work up into batches that would otherwise timeout if all the work was attempted at once, for example a long running SQL delete command.
92 lines
3.2 KiB
Go
92 lines
3.2 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
||
// SPDX-License-Identifier: BUSL-1.1
|
||
|
||
package scheduler
|
||
|
||
import (
|
||
"context"
|
||
"time"
|
||
|
||
"github.com/hashicorp/boundary/internal/errors"
|
||
)
|
||
|
||
// Job defines an interface for jobs that can be invoked by the scheduler.
|
||
// Multiple goroutines may invoke methods on a Job simultaneously.
|
||
type Job interface {
|
||
// 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.
|
||
Status() JobStatus
|
||
|
||
// Run starts the specified job and waits for it to complete.
|
||
//
|
||
// 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
|
||
|
||
// 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
|
||
// the job will be scheduled to run again immediately.
|
||
//
|
||
// If an error is returned, the error will be logged but the returned
|
||
// duration will still be used in scheduling.
|
||
NextRunIn(context.Context) (time.Duration, error)
|
||
|
||
// Name is the unique name of the job.
|
||
Name() string
|
||
|
||
// Description is the human readable description of the job.
|
||
Description() string
|
||
}
|
||
|
||
// 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.
|
||
//
|
||
// Retries is used to indicate how many times the job has retried
|
||
// accomplishing work. The value must be greater than or equal to zero.
|
||
//
|
||
// 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.
|
||
type JobStatus struct {
|
||
// The job's work items
|
||
Completed int // number of items processed
|
||
Total int // total number of items to be processed
|
||
|
||
// The job's liveliness
|
||
Retries int // number of times the job has retried work
|
||
}
|
||
|
||
func validateJob(ctx context.Context, j Job) error {
|
||
const op = "scheduler.validateJob"
|
||
if j == nil {
|
||
return errors.New(ctx, errors.InvalidParameter, op, "missing job")
|
||
}
|
||
if j.Name() == "" {
|
||
return errors.New(ctx, errors.InvalidParameter, op, "missing name")
|
||
}
|
||
if j.Description() == "" {
|
||
return errors.New(ctx, errors.InvalidParameter, op, "missing description")
|
||
}
|
||
return nil
|
||
}
|