scheduler: merge Reserve and Unreserve plugins
Previously, separate interfaces were defined for Reserve and Unreserve plugins. However, in nearly all cases, a plugin that allocates a resource using Reserve will likely want to register itself for Unreserve as well in order to free the allocated resource at the end of a failed scheduling/binding cycle. Having separate plugins for Reserve and Unreserve also adds unnecessary config toil. To that end, this patch aims to merge the two plugins into a single interface called a ReservePlugin that requires implementing both the Reserve and Unreserve methods.
This commit is contained in:
@@ -50,7 +50,7 @@ func (s *stateData) Clone() framework.StateData {
|
||||
return copy
|
||||
}
|
||||
|
||||
// Reserve is the functions invoked by the framework at "reserve" extension point.
|
||||
// Reserve is the function invoked by the framework at "reserve" extension point.
|
||||
func (mc CommunicatingPlugin) Reserve(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodeName string) *framework.Status {
|
||||
if pod == nil {
|
||||
return framework.NewStatus(framework.Error, "pod cannot be nil")
|
||||
@@ -63,7 +63,20 @@ func (mc CommunicatingPlugin) Reserve(ctx context.Context, state *framework.Cycl
|
||||
return nil
|
||||
}
|
||||
|
||||
// PreBind is the functions invoked by the framework at "prebind" extension point.
|
||||
// Unreserve is the function invoked by the framework when any error happens
|
||||
// during "reserve" extension point or later.
|
||||
func (mc CommunicatingPlugin) Unreserve(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodeName string) {
|
||||
if pod.Name == "my-test-pod" {
|
||||
state.Lock()
|
||||
// The pod is at the end of its lifecycle -- let's clean up the allocated
|
||||
// resources. In this case, our clean up is simply deleting the key written
|
||||
// in the Reserve operation.
|
||||
state.Delete(framework.StateKey(pod.Name))
|
||||
state.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
// PreBind is the function invoked by the framework at "prebind" extension point.
|
||||
func (mc CommunicatingPlugin) PreBind(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodeName string) *framework.Status {
|
||||
if pod == nil {
|
||||
return framework.NewStatus(framework.Error, "pod cannot be nil")
|
||||
|
@@ -31,9 +31,8 @@ import (
|
||||
// This plugin is stateful. It receives arguments at initialization (NewMultipointPlugin)
|
||||
// and changes its state when it is executed.
|
||||
type MultipointExample struct {
|
||||
mpState map[int]string
|
||||
numRuns int
|
||||
mu sync.RWMutex
|
||||
executionPoints []string
|
||||
mu sync.RWMutex
|
||||
}
|
||||
|
||||
var _ framework.ReservePlugin = &MultipointExample{}
|
||||
@@ -47,19 +46,35 @@ func (mp *MultipointExample) Name() string {
|
||||
return Name
|
||||
}
|
||||
|
||||
// Reserve is the functions invoked by the framework at "reserve" extension point.
|
||||
// Reserve is the function invoked by the framework at "reserve" extension
|
||||
// point. In this trivial example, the Reserve method allocates an array of
|
||||
// strings.
|
||||
func (mp *MultipointExample) Reserve(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodeName string) *framework.Status {
|
||||
// Reserve is not called concurrently, and so we don't need to lock.
|
||||
mp.numRuns++
|
||||
mp.executionPoints = append(mp.executionPoints, "reserve")
|
||||
return nil
|
||||
}
|
||||
|
||||
// PreBind is the functions invoked by the framework at "prebind" extension point.
|
||||
// Unreserve is the function invoked by the framework when any error happens
|
||||
// during "reserve" extension point or later. In this example, the Unreserve
|
||||
// method loses its reference to the string slice, allowing it to be garbage
|
||||
// collected, and thereby "unallocating" the reserved resources.
|
||||
func (mp *MultipointExample) Unreserve(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodeName string) {
|
||||
// Unlike Reserve, the Unreserve method may be called concurrently since
|
||||
// there is no guarantee that there will only one unreserve operation at any
|
||||
// given point in time (for example, during the binding cycle).
|
||||
mp.mu.Lock()
|
||||
defer mp.mu.Unlock()
|
||||
mp.executionPoints = nil
|
||||
}
|
||||
|
||||
// PreBind is the function invoked by the framework at "prebind" extension
|
||||
// point.
|
||||
func (mp *MultipointExample) PreBind(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodeName string) *framework.Status {
|
||||
// PreBind could be called concurrently for different pods.
|
||||
mp.mu.Lock()
|
||||
defer mp.mu.Unlock()
|
||||
mp.numRuns++
|
||||
mp.executionPoints = append(mp.executionPoints, "pre-bind")
|
||||
if pod == nil {
|
||||
return framework.NewStatus(framework.Error, "pod must not be nil")
|
||||
}
|
||||
@@ -72,8 +87,6 @@ func New(config *runtime.Unknown, _ framework.FrameworkHandle) (framework.Plugin
|
||||
klog.Error("MultipointExample configuration cannot be empty")
|
||||
return nil, fmt.Errorf("MultipointExample configuration cannot be empty")
|
||||
}
|
||||
mp := MultipointExample{
|
||||
mpState: make(map[int]string),
|
||||
}
|
||||
mp := MultipointExample{}
|
||||
return &mp, nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user