github.com/kardianos/nomad@v0.1.3-0.20151022182107-b13df73ee850/scheduler/context.go (about)

     1  package scheduler
     2  
     3  import (
     4  	"log"
     5  	"regexp"
     6  
     7  	"github.com/hashicorp/go-version"
     8  	"github.com/hashicorp/nomad/nomad/structs"
     9  )
    10  
    11  // Context is used to track contextual information used for placement
    12  type Context interface {
    13  	// State is used to inspect the current global state
    14  	State() State
    15  
    16  	// Plan returns the current plan
    17  	Plan() *structs.Plan
    18  
    19  	// Logger provides a way to log
    20  	Logger() *log.Logger
    21  
    22  	// Metrics returns the current metrics
    23  	Metrics() *structs.AllocMetric
    24  
    25  	// Reset is invoked after making a placement
    26  	Reset()
    27  
    28  	// ProposedAllocs returns the proposed allocations for a node
    29  	// which is the existing allocations, removing evictions, and
    30  	// adding any planned placements.
    31  	ProposedAllocs(nodeID string) ([]*structs.Allocation, error)
    32  
    33  	// RegexpCache is a cache of regular expressions
    34  	RegexpCache() map[string]*regexp.Regexp
    35  
    36  	// ConstraintCache is a cache of version constraints
    37  	ConstraintCache() map[string]version.Constraints
    38  }
    39  
    40  // EvalCache is used to cache certain things during an evaluation
    41  type EvalCache struct {
    42  	reCache         map[string]*regexp.Regexp
    43  	constraintCache map[string]version.Constraints
    44  }
    45  
    46  func (e *EvalCache) RegexpCache() map[string]*regexp.Regexp {
    47  	if e.reCache == nil {
    48  		e.reCache = make(map[string]*regexp.Regexp)
    49  	}
    50  	return e.reCache
    51  }
    52  func (e *EvalCache) ConstraintCache() map[string]version.Constraints {
    53  	if e.constraintCache == nil {
    54  		e.constraintCache = make(map[string]version.Constraints)
    55  	}
    56  	return e.constraintCache
    57  }
    58  
    59  // EvalContext is a Context used during an Evaluation
    60  type EvalContext struct {
    61  	EvalCache
    62  	state   State
    63  	plan    *structs.Plan
    64  	logger  *log.Logger
    65  	metrics *structs.AllocMetric
    66  }
    67  
    68  // NewEvalContext constructs a new EvalContext
    69  func NewEvalContext(s State, p *structs.Plan, log *log.Logger) *EvalContext {
    70  	ctx := &EvalContext{
    71  		state:   s,
    72  		plan:    p,
    73  		logger:  log,
    74  		metrics: new(structs.AllocMetric),
    75  	}
    76  	return ctx
    77  }
    78  
    79  func (e *EvalContext) State() State {
    80  	return e.state
    81  }
    82  
    83  func (e *EvalContext) Plan() *structs.Plan {
    84  	return e.plan
    85  }
    86  
    87  func (e *EvalContext) Logger() *log.Logger {
    88  	return e.logger
    89  }
    90  
    91  func (e *EvalContext) Metrics() *structs.AllocMetric {
    92  	return e.metrics
    93  }
    94  
    95  func (e *EvalContext) SetState(s State) {
    96  	e.state = s
    97  }
    98  
    99  func (e *EvalContext) Reset() {
   100  	e.metrics = new(structs.AllocMetric)
   101  }
   102  
   103  func (e *EvalContext) ProposedAllocs(nodeID string) ([]*structs.Allocation, error) {
   104  	// Get the existing allocations
   105  	existingAlloc, err := e.state.AllocsByNode(nodeID)
   106  	if err != nil {
   107  		return nil, err
   108  	}
   109  
   110  	// Filter on alloc state
   111  	existingAlloc = structs.FilterTerminalAllocs(existingAlloc)
   112  
   113  	// Determine the proposed allocation by first removing allocations
   114  	// that are planned evictions and adding the new allocations.
   115  	proposed := existingAlloc
   116  	if update := e.plan.NodeUpdate[nodeID]; len(update) > 0 {
   117  		proposed = structs.RemoveAllocs(existingAlloc, update)
   118  	}
   119  	proposed = append(proposed, e.plan.NodeAllocation[nodeID]...)
   120  
   121  	// Ensure the return is not nil
   122  	if proposed == nil {
   123  		proposed = make([]*structs.Allocation, 0)
   124  	}
   125  	return proposed, nil
   126  }