open-nomad/scheduler/scheduler.go

88 lines
3.2 KiB
Go
Raw Normal View History

2015-07-28 23:03:15 +00:00
package scheduler
import (
"fmt"
"log"
2015-07-28 23:03:15 +00:00
"github.com/hashicorp/go-memdb"
2015-07-28 23:03:15 +00:00
"github.com/hashicorp/nomad/nomad/structs"
)
// BuiltinSchedulers contains the built in registered schedulers
// which are available
var BuiltinSchedulers = map[string]Factory{
2015-10-23 23:31:45 +00:00
structs.JobTypeService: NewServiceScheduler,
structs.JobTypeBatch: NewBatchScheduler,
structs.JobTypeSystem: NewSystemScheduler,
}
2015-07-28 23:03:15 +00:00
// NewScheduler is used to instantiate and return a new scheduler
// given the scheduler name, initial state, and planner.
func NewScheduler(name string, logger *log.Logger, state State, planner Planner) (Scheduler, error) {
2015-07-28 23:03:15 +00:00
// Lookup the factory function
factory, ok := BuiltinSchedulers[name]
if !ok {
return nil, fmt.Errorf("unknown scheduler '%s'", name)
}
// Instantiate the scheduler
sched := factory(logger, state, planner)
2015-07-28 23:03:15 +00:00
return sched, nil
}
// Factory is used to instantiate a new Scheduler
type Factory func(*log.Logger, State, Planner) Scheduler
2015-07-28 23:03:15 +00:00
// Scheduler is the top level instance for a scheduler. A scheduler is
// meant to only encapsulate business logic, pushing the various plumbing
// into Nomad itself. They are invoked to process a single evaluation at
// a time. The evaluation may result in task allocations which are computed
// optimistically, as there are many concurrent evaluations being processed.
// The task allocations are submitted as a plan, and the current leader will
// coordinate the commmits to prevent oversubscription or improper allocations
// based on stale state.
type Scheduler interface {
// Process is used to handle a new evaluation. The scheduler is free to
// apply any logic necessary to make the task placements. The state and
// planner will be provided prior to any invocations of process.
Process(*structs.Evaluation) error
}
// State is an immutable view of the global state. This allows schedulers
// to make intelligent decisions based on allocations of other schedulers
// and to enforce complex constraints that require more information than
// is available to a local state scheduler.
type State interface {
// Nodes returns an iterator over all the nodes.
// The type of each result is *structs.Node
Nodes() (memdb.ResultIterator, error)
// AllocsByJob returns the allocations by JobID
AllocsByJob(jobID string) ([]*structs.Allocation, error)
2015-08-13 18:54:59 +00:00
// AllocsByNode returns all the allocations by node
AllocsByNode(node string) ([]*structs.Allocation, error)
// GetNodeByID is used to lookup a node by ID
2015-09-07 03:56:38 +00:00
NodeByID(nodeID string) (*structs.Node, error)
2015-08-11 23:41:48 +00:00
// GetJobByID is used to lookup a job by ID
2015-09-07 03:56:38 +00:00
JobByID(id string) (*structs.Job, error)
2015-07-28 23:03:15 +00:00
}
// Planner interface is used to submit a task allocation plan.
type Planner interface {
// SubmitPlan is used to submit a plan for consideration.
// This will return a PlanResult or an error. It is possible
// that this will result in a state refresh as well.
SubmitPlan(*structs.Plan) (*structs.PlanResult, State, error)
2015-08-15 21:25:00 +00:00
// UpdateEval is used to update an evaluation. This should update
// a copy of the input evaluation since that should be immutable.
UpdateEval(*structs.Evaluation) error
// CreateEval is used to create an evaluation. This should set the
// PreviousEval to that of the current evaluation.
CreateEval(*structs.Evaluation) error
2015-07-28 23:03:15 +00:00
}