From 9c17cceaa335077f0d966ea4701f1aed30801144 Mon Sep 17 00:00:00 2001 From: Armon Dadgar Date: Tue, 11 Aug 2015 14:04:04 -0700 Subject: [PATCH] scheduler: check node status before evicting --- scheduler/scheduler.go | 3 +++ scheduler/service_sched.go | 17 +++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/scheduler/scheduler.go b/scheduler/scheduler.go index 165e6d79e..82ee4879b 100644 --- a/scheduler/scheduler.go +++ b/scheduler/scheduler.go @@ -57,6 +57,9 @@ type State interface { // AllocsByJob returns the allocations by JobID AllocsByJob(jobID string) ([]*structs.Allocation, error) + + // GetNodeByID is used to lookup a node by ID + GetNodeByID(nodeID string) (*structs.Node, error) } // Planner interface is used to submit a task allocation plan. diff --git a/scheduler/service_sched.go b/scheduler/service_sched.go index b64c14220..6e87fd2c1 100644 --- a/scheduler/service_sched.go +++ b/scheduler/service_sched.go @@ -52,6 +52,23 @@ func (s *ServiceScheduler) handleJobRegister(eval *structs.Evaluation) error { // handleJobDeregister is used to handle a job being deregistered func (s *ServiceScheduler) handleJobDeregister(eval *structs.Evaluation) error { START: + // Lookup the node ID + node, err := s.state.GetNodeByID(eval.NodeID) + if err != nil { + return fmt.Errorf("failed to get node '%s': %v", + eval.NodeID, err) + } + + // Could be a potential race, and the node is actually fine + if node != nil { + switch node.Status { + case structs.NodeStatusInit, structs.NodeStatusReady, structs.NodeStatusMaint: + s.logger.Printf("[DEBUG] sched: (eval %s) not evicting node %s allocs, status %s", + eval.ID, eval.NodeID, node.Status) + return nil + } + } + // Lookup the allocations by JobID allocs, err := s.state.AllocsByJob(eval.JobID) if err != nil {