Remove user-specifiable gc threshold

This commit is contained in:
Alex Dadgar 2015-12-15 13:07:25 -08:00
parent 2218a79815
commit f1d88bdf86
11 changed files with 27 additions and 95 deletions

View File

@ -107,12 +107,6 @@ type UpdateStrategy struct {
MaxParallel int
}
// JobGCConfig configures the garbage collection policy of a job.
type JobGCConfig struct {
Enabled bool
Threshold time.Duration
}
// Job is used to serialize a job.
type Job struct {
Region string
@ -125,7 +119,7 @@ type Job struct {
Constraints []*Constraint
TaskGroups []*TaskGroup
Update *UpdateStrategy
GC *JobGCConfig
GC bool
Meta map[string]string
Status string
StatusDescription string

View File

@ -723,7 +723,7 @@ func parsePeriodic(result **structs.PeriodicConfig, list *ast.ObjectList) error
return nil
}
func parseGC(result **structs.JobGCConfig, list *ast.ObjectList) error {
func parseGC(result *bool, list *ast.ObjectList) error {
list = list.Elem()
if len(list.Items) > 1 {
return fmt.Errorf("only one 'gc' block allowed per job")
@ -738,23 +738,17 @@ func parseGC(result **structs.JobGCConfig, list *ast.ObjectList) error {
}
// Enabled by default if the gc block exists.
enabled := false
if value, ok := m["enabled"]; !ok {
m["Enabled"] = true
enabled = true
} else {
enabled, err := parseBool(value)
var err error
enabled, err = parseBool(value)
if err != nil {
return fmt.Errorf("gc.enabled should be set to true or false; %v", err)
}
m["Enabled"] = enabled
}
dec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
DecodeHook: mapstructure.StringToTimeDurationHookFunc(),
WeaklyTypedInput: true,
Result: result,
})
if err != nil {
return err
}
return dec.Decode(m)
*result = enabled
return nil
}

View File

@ -254,10 +254,7 @@ func TestParse(t *testing.T) {
Priority: 50,
Region: "global",
Type: "service",
GC: &structs.JobGCConfig{
Enabled: true,
Threshold: 2 * time.Hour,
},
GC: true,
},
false,
},

View File

@ -1,5 +1,5 @@
job "foo" {
gc {
threshold = "2h"
enabled = true
}
}

View File

@ -135,6 +135,10 @@ type Config struct {
// available for garbage collection.
JobGCInterval time.Duration
// JobGCThreshold is how old a job must be before it eligible for GC. This gives
// the user time to inspect the job.
JobGCThreshold time.Duration
// NodeGCInterval is how often we dispatch a job to GC failed nodes.
NodeGCInterval time.Duration
@ -207,6 +211,7 @@ func DefaultConfig() *Config {
EvalGCInterval: 5 * time.Minute,
EvalGCThreshold: 1 * time.Hour,
JobGCInterval: 5 * time.Minute,
JobGCThreshold: 4 * time.Hour,
NodeGCInterval: 5 * time.Minute,
NodeGCThreshold: 24 * time.Hour,
EvalNackTimeout: 60 * time.Second,

View File

@ -50,6 +50,10 @@ func (c *CoreScheduler) jobGC(eval *structs.Evaluation) error {
// Get the time table to calculate GC cutoffs.
tt := c.srv.fsm.TimeTable()
cutoff := time.Now().UTC().Add(-1 * c.srv.config.JobGCThreshold)
oldThreshold := tt.NearestIndex(cutoff)
c.srv.logger.Printf("[DEBUG] sched.core: job GC: scanning before index %d (%v)",
oldThreshold, c.srv.config.JobGCThreshold)
// Collect the allocations and evaluations to GC
var gcAlloc, gcEval, gcJob []string
@ -57,8 +61,6 @@ func (c *CoreScheduler) jobGC(eval *structs.Evaluation) error {
OUTER:
for i := jIter.Next(); i != nil; i = jIter.Next() {
job := i.(*structs.Job)
cutoff := time.Now().UTC().Add(-1 * job.GC.Threshold)
oldThreshold := tt.NearestIndex(cutoff)
// Ignore new jobs.
if job.CreateIndex > oldThreshold {

View File

@ -145,11 +145,7 @@ func TestCoreScheduler_JobGC(t *testing.T) {
// Insert job.
state := s1.fsm.State()
job := mock.Job()
threshold := 1 * time.Hour
job.GC = &structs.JobGCConfig{
Enabled: true,
Threshold: threshold,
}
job.GC = true
err := state.UpsertJob(1000, job)
if err != nil {
t.Fatalf("test(%s) err: %v", test.test, err)

View File

@ -121,11 +121,7 @@ func jobIsGCable(obj interface{}) (bool, error) {
return false, fmt.Errorf("Unexpected type: %v", obj)
}
if j.GC == nil || !j.GC.Enabled {
return false, nil
}
return true, nil
return j.GC, nil
}
// evalTableSchema returns the MemDB schema for the eval table.

View File

@ -486,10 +486,7 @@ func TestStateStore_JobsByGC(t *testing.T) {
for i := 0; i < 10; i++ {
job := mock.Job()
job.GC = &structs.JobGCConfig{
Enabled: true,
Threshold: structs.DefaultJobGCThreshold,
}
job.GC = true
gc = append(gc, job)
if err := state.UpsertJob(2000+uint64(i), job); err != nil {

View File

@ -766,7 +766,7 @@ type Job struct {
// GC is used to mark the job as available for garbage collection after it
// has no outstanding evaluations or allocations.
GC *JobGCConfig
GC bool
// Meta is used to associate arbitrary metadata with this
// job. This is opaque to Nomad.
@ -788,11 +788,6 @@ type Job struct {
func (j *Job) InitFields() {
// Initialize the service block.
j.InitAllServiceFields()
// Initalize the GC policy
if j.GC != nil {
j.GC.Init()
}
}
// InitAllServiceFields traverses all Task Groups and makes them
@ -870,13 +865,6 @@ func (j *Job) Validate() error {
fmt.Errorf("Periodic can only be used with %q scheduler", JobTypeBatch))
}
// Validate the GC config.
if j.GC != nil {
if err := j.GC.Validate(); err != nil {
mErr.Errors = append(mErr.Errors, err)
}
}
return mErr.ErrorOrNil()
}
@ -922,37 +910,6 @@ type JobListStub struct {
ModifyIndex uint64
}
const (
// DefaultJobGCThreshold is the default threshold for garbage collecting
// eligible jobs.
DefaultJobGCThreshold = 4 * time.Hour
)
// JobGCConfig configures the garbage collection policy of a job.
type JobGCConfig struct {
// Enabled determines whether the job is eligible for garbage collection.
Enabled bool
// Threshold is how old a job must be before it eligible for GC. This gives
// the user time to inspect the job.
Threshold time.Duration
}
// Init sets the Threshold time to its default value if it is un-specified but
// garbage collection is enabled.
func (gc *JobGCConfig) Init() {
if gc.Enabled && gc.Threshold == 0 {
gc.Threshold = DefaultJobGCThreshold
}
}
func (gc *JobGCConfig) Validate() error {
if gc.Threshold < 0 {
return fmt.Errorf("job GC threshold must be positive: %v", gc.Threshold)
}
return nil
}
// UpdateStrategy is used to modify how updates are done
type UpdateStrategy struct {
// Stagger is the amount of time between the updates

View File

@ -156,7 +156,7 @@ The `job` object supports the following keys:
and "h" suffix can be used, such as "30s". Both values default to zero,
which disables rolling updates.
* `gc` - Specifies the job's garbage collection configuration. This allows jobs
* `gc` - Toggles the job's eligibility for garbage collection. This allows jobs
to be garbage collected when all their evaluations and allocations are
terminal. The `gc` block has the following format:
@ -164,20 +164,14 @@ The `job` object supports the following keys:
"gc" {
// Enabled is set to true by default if the "gc" block is included.
enabled = true
// Threshold is a duration that configures how old a job must be
// before it is garbage collected.
threshold = "4h"
}
// Equivalent configuration.
"gc" {}
```
* `enabled`: Toggles the eligibility of a job for garbage collection.
* `threshold`: `threshold` is a string that should be parseable as a
[time.Duration](https://golang.org/pkg/time/#ParseDuration). A job will
only be garbage collected after the job, its evaluations and allocations
are all older than the threshold.
### Task Group