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