...

Source file src/k8s.io/kubernetes/pkg/scheduler/framework/cycle_state.go

Documentation: k8s.io/kubernetes/pkg/scheduler/framework

     1  /*
     2  Copyright 2019 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package framework
    18  
    19  import (
    20  	"errors"
    21  	"sync"
    22  
    23  	"k8s.io/apimachinery/pkg/util/sets"
    24  )
    25  
    26  var (
    27  	// ErrNotFound is the not found error message.
    28  	ErrNotFound = errors.New("not found")
    29  )
    30  
    31  // StateData is a generic type for arbitrary data stored in CycleState.
    32  type StateData interface {
    33  	// Clone is an interface to make a copy of StateData. For performance reasons,
    34  	// clone should make shallow copies for members (e.g., slices or maps) that are not
    35  	// impacted by PreFilter's optional AddPod/RemovePod methods.
    36  	Clone() StateData
    37  }
    38  
    39  // StateKey is the type of keys stored in CycleState.
    40  type StateKey string
    41  
    42  // CycleState provides a mechanism for plugins to store and retrieve arbitrary data.
    43  // StateData stored by one plugin can be read, altered, or deleted by another plugin.
    44  // CycleState does not provide any data protection, as all plugins are assumed to be
    45  // trusted.
    46  // Note: CycleState uses a sync.Map to back the storage, because it is thread safe. It's aimed to optimize for the "write once and read many times" scenarios.
    47  // It is the recommended pattern used in all in-tree plugins - plugin-specific state is written once in PreFilter/PreScore and afterward read many times in Filter/Score.
    48  type CycleState struct {
    49  	// storage is keyed with StateKey, and valued with StateData.
    50  	storage sync.Map
    51  	// if recordPluginMetrics is true, metrics.PluginExecutionDuration will be recorded for this cycle.
    52  	recordPluginMetrics bool
    53  	// SkipFilterPlugins are plugins that will be skipped in the Filter extension point.
    54  	SkipFilterPlugins sets.Set[string]
    55  	// SkipScorePlugins are plugins that will be skipped in the Score extension point.
    56  	SkipScorePlugins sets.Set[string]
    57  }
    58  
    59  // NewCycleState initializes a new CycleState and returns its pointer.
    60  func NewCycleState() *CycleState {
    61  	return &CycleState{}
    62  }
    63  
    64  // ShouldRecordPluginMetrics returns whether metrics.PluginExecutionDuration metrics should be recorded.
    65  func (c *CycleState) ShouldRecordPluginMetrics() bool {
    66  	if c == nil {
    67  		return false
    68  	}
    69  	return c.recordPluginMetrics
    70  }
    71  
    72  // SetRecordPluginMetrics sets recordPluginMetrics to the given value.
    73  func (c *CycleState) SetRecordPluginMetrics(flag bool) {
    74  	if c == nil {
    75  		return
    76  	}
    77  	c.recordPluginMetrics = flag
    78  }
    79  
    80  // Clone creates a copy of CycleState and returns its pointer. Clone returns
    81  // nil if the context being cloned is nil.
    82  func (c *CycleState) Clone() *CycleState {
    83  	if c == nil {
    84  		return nil
    85  	}
    86  	copy := NewCycleState()
    87  	// Safe copy storage in case of overwriting.
    88  	c.storage.Range(func(k, v interface{}) bool {
    89  		copy.storage.Store(k, v.(StateData).Clone())
    90  		return true
    91  	})
    92  	// The below are not mutated, so we don't have to safe copy.
    93  	copy.recordPluginMetrics = c.recordPluginMetrics
    94  	copy.SkipFilterPlugins = c.SkipFilterPlugins
    95  	copy.SkipScorePlugins = c.SkipScorePlugins
    96  
    97  	return copy
    98  }
    99  
   100  // Read retrieves data with the given "key" from CycleState. If the key is not
   101  // present, ErrNotFound is returned.
   102  //
   103  // See CycleState for notes on concurrency.
   104  func (c *CycleState) Read(key StateKey) (StateData, error) {
   105  	if v, ok := c.storage.Load(key); ok {
   106  		return v.(StateData), nil
   107  	}
   108  	return nil, ErrNotFound
   109  }
   110  
   111  // Write stores the given "val" in CycleState with the given "key".
   112  //
   113  // See CycleState for notes on concurrency.
   114  func (c *CycleState) Write(key StateKey, val StateData) {
   115  	c.storage.Store(key, val)
   116  }
   117  
   118  // Delete deletes data with the given key from CycleState.
   119  //
   120  // See CycleState for notes on concurrency.
   121  func (c *CycleState) Delete(key StateKey) {
   122  	c.storage.Delete(key)
   123  }
   124  

View as plain text