// CreateEval is used to create a new evaluation. This allows // the worker to act as the planner for the scheduler. func (w *Worker) CreateEval(eval *structs.Evaluation) error { // Check for a shutdown before plan submission if w.srv.IsShutdown() { return fmt.Errorf("shutdown while planning") } defer metrics.MeasureSince([]string{"nomad", "worker", "create_eval"}, time.Now()) // Store the snapshot index in the eval eval.SnapshotIndex = w.snapshotIndex // Setup the request req := structs.EvalUpdateRequest{ Evals: []*structs.Evaluation{eval}, EvalToken: w.evalToken, WriteRequest: structs.WriteRequest{ Region: w.srv.config.Region, }, } var resp structs.GenericResponse SUBMIT: // Make the RPC call if err := w.srv.RPC("Eval.Create", &req, &resp); err != nil { w.logger.Printf("[ERR] worker: failed to create evaluation %#v: %v", eval, err) if w.shouldResubmit(err) && !w.backoffErr(backoffBaselineSlow, backoffLimitSlow) { goto SUBMIT } return err } else { w.logger.Printf("[DEBUG] worker: created evaluation %#v", eval) w.backoffReset() } return nil }
// ReblockEval is used to reinsert a blocked evaluation into the blocked eval // tracker. This allows the worker to act as the planner for the scheduler. func (w *Worker) ReblockEval(eval *structs.Evaluation) error { // Check for a shutdown before plan submission if w.srv.IsShutdown() { return fmt.Errorf("shutdown while planning") } defer metrics.MeasureSince([]string{"nomad", "worker", "reblock_eval"}, time.Now()) // Update the evaluation if the queued jobs is not same as what is // recorded in the job summary summary, err := w.srv.fsm.state.JobSummaryByID(eval.JobID) if err != nil { return fmt.Errorf("couldn't retreive job summary: %v", err) } if summary != nil { var hasChanged bool for tg, summary := range summary.Summary { if queued, ok := eval.QueuedAllocations[tg]; ok { if queued != summary.Queued { hasChanged = true break } } } if hasChanged { if err := w.UpdateEval(eval); err != nil { return err } } } // Store the snapshot index in the eval eval.SnapshotIndex = w.snapshotIndex // Setup the request req := structs.EvalUpdateRequest{ Evals: []*structs.Evaluation{eval}, EvalToken: w.evalToken, WriteRequest: structs.WriteRequest{ Region: w.srv.config.Region, }, } var resp structs.GenericResponse SUBMIT: // Make the RPC call if err := w.srv.RPC("Eval.Reblock", &req, &resp); err != nil { w.logger.Printf("[ERR] worker: failed to reblock evaluation %#v: %v", eval, err) if w.shouldResubmit(err) && !w.backoffErr(backoffBaselineSlow, backoffLimitSlow) { goto SUBMIT } return err } else { w.logger.Printf("[DEBUG] worker: reblocked evaluation %#v", eval) w.backoffReset() } return nil }