From e97da60df1cc5f62660a06cd5b8e41e09aca8bfa Mon Sep 17 00:00:00 2001 From: michaelawyu Date: Fri, 2 Jun 2023 08:13:17 +0800 Subject: [PATCH 1/3] Added framework cycle state --- pkg/scheduler/framework/cyclestate.go | 73 ++++++++++++++++++++++ pkg/scheduler/framework/cyclestate_test.go | 23 +++++++ 2 files changed, 96 insertions(+) create mode 100644 pkg/scheduler/framework/cyclestate.go create mode 100644 pkg/scheduler/framework/cyclestate_test.go diff --git a/pkg/scheduler/framework/cyclestate.go b/pkg/scheduler/framework/cyclestate.go new file mode 100644 index 000000000..6c162f9d1 --- /dev/null +++ b/pkg/scheduler/framework/cyclestate.go @@ -0,0 +1,73 @@ +/* +Copyright (c) Microsoft Corporation. +Licensed under the MIT license. +*/ + +package framework + +import ( + "fmt" + "sync" + + "k8s.io/apimachinery/pkg/util/sets" +) + +// StateKey is the key for a state value stored in a CycleState. +type StateKey string + +// StateValue is the value stored in a CycleState under a specific key. +type StateValue interface{} + +// CycleStatePluginReadWriter is an interface through which plugins can store and retrieve data. +type CycleStatePluginReadWriter interface { + Read(key StateKey) (StateValue, error) + Write(key StateKey, val StateValue) + Delete(key StateKey) +} + +// CycleState is, similar to its namesake in kube-scheduler, provides a way for plugins to +// store and retrieve arbitrary data during a scheduling cycle. The scheduler also uses +// this struct to keep some global states during a scheduling cycle; note that these +// state are only accessible to the scheduler itself, not to plugins. +// +// It uses a sync.Map for concurrency-safe storage. +type cycleState struct { + // store is a concurrency-safe store (a map). + store sync.Map + + // skippedFilterPlugins are a set of Filter plugins that will be skipped during the scheduling + // cycle. + skippedFilterPlugins sets.String + // skippedScorePlugins are a set of Score plugins that will be skipped during the scheduling + // cycle. + skippedScorePlugins sets.String + + // expectedBatchSize is the number of bindings that the scheduler should create. + expectedBatchSize int + // batchSizeLimit is the number of bindings that the scheduler can actually create for the + // scheduling cycle. + batchSizeLimit int +} + +// Read retrieves a value from CycleState by a key. +func (c *cycleState) Read(key StateKey) (StateValue, error) { + if v, ok := c.store.Load(key); ok { + return v, nil + } + return nil, fmt.Errorf("key %s is not found", key) +} + +// Write stores a value in CycleState under a key. +func (c *cycleState) Write(key StateKey, val StateValue) { + c.store.Store(key, val) +} + +// Delete deletes a key from CycleState. +func (c *cycleState) Delete(key StateKey) { + c.store.Delete(key) +} + +// NewCycleState creates a CycleState. +func NewCycleState() *cycleState { + return &cycleState{} +} diff --git a/pkg/scheduler/framework/cyclestate_test.go b/pkg/scheduler/framework/cyclestate_test.go new file mode 100644 index 000000000..b39e659ed --- /dev/null +++ b/pkg/scheduler/framework/cyclestate_test.go @@ -0,0 +1,23 @@ +/* +Copyright (c) Microsoft Corporation. +Licensed under the MIT license. +*/ + +package framework + +import "testing" + +// TestCycleStateBasicOps tests the basic ops (Read, Write, and Delete) of a CycleState. +func TestCycleStateBasicOps(t *testing.T) { + cs := NewCycleState() + + k, v := "key", "value" + cs.Write(StateKey(k), StateValue(v)) + if out, err := cs.Read("key"); out != "value" || err != nil { + t.Fatalf("Read(%v) = %v, %v, want %v, nil", k, out, err, v) + } + cs.Delete(StateKey(k)) + if out, err := cs.Read("key"); out != nil || err == nil { + t.Fatalf("Read(%v) = %v, %v, want nil, not found error", k, out, err) + } +} From 5ec3d223df6c48c553ed89b09d4f426ce889a77f Mon Sep 17 00:00:00 2001 From: michaelawyu Date: Fri, 2 Jun 2023 08:25:41 +0800 Subject: [PATCH 2/3] Minor fixes --- pkg/scheduler/framework/cyclestate.go | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/pkg/scheduler/framework/cyclestate.go b/pkg/scheduler/framework/cyclestate.go index 6c162f9d1..cd8841102 100644 --- a/pkg/scheduler/framework/cyclestate.go +++ b/pkg/scheduler/framework/cyclestate.go @@ -8,8 +8,6 @@ package framework import ( "fmt" "sync" - - "k8s.io/apimachinery/pkg/util/sets" ) // StateKey is the key for a state value stored in a CycleState. @@ -31,10 +29,12 @@ type CycleStatePluginReadWriter interface { // state are only accessible to the scheduler itself, not to plugins. // // It uses a sync.Map for concurrency-safe storage. -type cycleState struct { +type CycleState struct { // store is a concurrency-safe store (a map). store sync.Map + /** + // TO-DO (chenyu1): uncomment when the fields are used. // skippedFilterPlugins are a set of Filter plugins that will be skipped during the scheduling // cycle. skippedFilterPlugins sets.String @@ -47,10 +47,11 @@ type cycleState struct { // batchSizeLimit is the number of bindings that the scheduler can actually create for the // scheduling cycle. batchSizeLimit int + **/ } // Read retrieves a value from CycleState by a key. -func (c *cycleState) Read(key StateKey) (StateValue, error) { +func (c *CycleState) Read(key StateKey) (StateValue, error) { if v, ok := c.store.Load(key); ok { return v, nil } @@ -58,16 +59,16 @@ func (c *cycleState) Read(key StateKey) (StateValue, error) { } // Write stores a value in CycleState under a key. -func (c *cycleState) Write(key StateKey, val StateValue) { +func (c *CycleState) Write(key StateKey, val StateValue) { c.store.Store(key, val) } // Delete deletes a key from CycleState. -func (c *cycleState) Delete(key StateKey) { +func (c *CycleState) Delete(key StateKey) { c.store.Delete(key) } // NewCycleState creates a CycleState. -func NewCycleState() *cycleState { - return &cycleState{} +func NewCycleState() *CycleState { + return &CycleState{} } From 2ac0ae8444949118293e7d663b6205ec733b63ef Mon Sep 17 00:00:00 2001 From: michaelawyu Date: Mon, 5 Jun 2023 11:37:53 +0800 Subject: [PATCH 3/3] Minor fixes --- pkg/scheduler/framework/cyclestate.go | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/pkg/scheduler/framework/cyclestate.go b/pkg/scheduler/framework/cyclestate.go index cd8841102..07a10a421 100644 --- a/pkg/scheduler/framework/cyclestate.go +++ b/pkg/scheduler/framework/cyclestate.go @@ -32,22 +32,6 @@ type CycleStatePluginReadWriter interface { type CycleState struct { // store is a concurrency-safe store (a map). store sync.Map - - /** - // TO-DO (chenyu1): uncomment when the fields are used. - // skippedFilterPlugins are a set of Filter plugins that will be skipped during the scheduling - // cycle. - skippedFilterPlugins sets.String - // skippedScorePlugins are a set of Score plugins that will be skipped during the scheduling - // cycle. - skippedScorePlugins sets.String - - // expectedBatchSize is the number of bindings that the scheduler should create. - expectedBatchSize int - // batchSizeLimit is the number of bindings that the scheduler can actually create for the - // scheduling cycle. - batchSizeLimit int - **/ } // Read retrieves a value from CycleState by a key.