github.com/kardianos/nomad@v0.1.3-0.20151022182107-b13df73ee850/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  	// GetNodeByID is used to lookup a node by ID
    67  	NodeByID(nodeID string) (*structs.Node, error)
    68  
    69  	// GetJobByID is used to lookup a job by ID
    70  	JobByID(id string) (*structs.Job, error)
    71  }
    72  
    73  // Planner interface is used to submit a task allocation plan.
    74  type Planner interface {
    75  	// SubmitPlan is used to submit a plan for consideration.
    76  	// This will return a PlanResult or an error. It is possible
    77  	// that this will result in a state refresh as well.
    78  	SubmitPlan(*structs.Plan) (*structs.PlanResult, State, error)
    79  
    80  	// UpdateEval is used to update an evaluation. This should update
    81  	// a copy of the input evaluation since that should be immutable.
    82  	UpdateEval(*structs.Evaluation) error
    83  
    84  	// CreateEval is used to create an evaluation. This should set the
    85  	// PreviousEval to that of the current evaluation.
    86  	CreateEval(*structs.Evaluation) error
    87  }