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