github.com/mattyr/nomad@v0.3.3-0.20160919021406-3485a065154a/scheduler/scheduler.go (about) 1 package scheduler 2 3 import ( 4 "fmt" 5 "log" 6 7 "github.com/hashicorp/go-memdb" 8 "github.com/hashicorp/nomad/nomad/structs" 9 ) 10 11 // BuiltinSchedulers contains the built in registered schedulers 12 // which are available 13 var BuiltinSchedulers = map[string]Factory{ 14 "service": NewServiceScheduler, 15 "batch": NewBatchScheduler, 16 "system": NewSystemScheduler, 17 } 18 19 // NewScheduler is used to instantiate and return a new scheduler 20 // given the scheduler name, initial state, and planner. 21 func NewScheduler(name string, logger *log.Logger, state State, planner Planner) (Scheduler, error) { 22 // Lookup the factory function 23 factory, ok := BuiltinSchedulers[name] 24 if !ok { 25 return nil, fmt.Errorf("unknown scheduler '%s'", name) 26 } 27 28 // Instantiate the scheduler 29 sched := factory(logger, state, planner) 30 return sched, nil 31 } 32 33 // Factory is used to instantiate a new Scheduler 34 type Factory func(*log.Logger, State, Planner) Scheduler 35 36 // Scheduler is the top level instance for a scheduler. A scheduler is 37 // meant to only encapsulate business logic, pushing the various plumbing 38 // into Nomad itself. They are invoked to process a single evaluation at 39 // a time. The evaluation may result in task allocations which are computed 40 // optimistically, as there are many concurrent evaluations being processed. 41 // The task allocations are submitted as a plan, and the current leader will 42 // coordinate the commmits to prevent oversubscription or improper allocations 43 // based on stale state. 44 type Scheduler interface { 45 // Process is used to handle a new evaluation. The scheduler is free to 46 // apply any logic necessary to make the task placements. The state and 47 // planner will be provided prior to any invocations of process. 48 Process(*structs.Evaluation) error 49 } 50 51 // State is an immutable view of the global state. This allows schedulers 52 // to make intelligent decisions based on allocations of other schedulers 53 // and to enforce complex constraints that require more information than 54 // is available to a local state scheduler. 55 type State interface { 56 // Nodes returns an iterator over all the nodes. 57 // The type of each result is *structs.Node 58 Nodes() (memdb.ResultIterator, error) 59 60 // AllocsByJob returns the allocations by JobID 61 AllocsByJob(jobID string) ([]*structs.Allocation, error) 62 63 // AllocsByNode returns all the allocations by node 64 AllocsByNode(node string) ([]*structs.Allocation, error) 65 66 // AllocsByNodeTerminal returns all the allocations by node filtering by terminal status 67 AllocsByNodeTerminal(node string, terminal bool) ([]*structs.Allocation, error) 68 69 // GetNodeByID is used to lookup a node by ID 70 NodeByID(nodeID string) (*structs.Node, error) 71 72 // GetJobByID is used to lookup a job by ID 73 JobByID(id string) (*structs.Job, error) 74 } 75 76 // Planner interface is used to submit a task allocation plan. 77 type Planner interface { 78 // SubmitPlan is used to submit a plan for consideration. 79 // This will return a PlanResult or an error. It is possible 80 // that this will result in a state refresh as well. 81 SubmitPlan(*structs.Plan) (*structs.PlanResult, State, error) 82 83 // UpdateEval is used to update an evaluation. This should update 84 // a copy of the input evaluation since that should be immutable. 85 UpdateEval(*structs.Evaluation) error 86 87 // CreateEval is used to create an evaluation. This should set the 88 // PreviousEval to that of the current evaluation. 89 CreateEval(*structs.Evaluation) error 90 91 // ReblockEval takes a blocked evaluation and re-inserts it into the blocked 92 // evaluation tracker. This update occurs only in-memory on the leader. The 93 // evaluation must exist in a blocked state prior to this being called such 94 // that on leader changes, the evaluation will be reblocked properly. 95 ReblockEval(*structs.Evaluation) error 96 }