-
Notifications
You must be signed in to change notification settings - Fork 96
Initial Scheduler Subsystem interface #845
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
4d263e8
6e02250
ac0ce0a
0a2e3e0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,77 @@ | ||||||
# Scheduling Subsystem Architecture | ||||||
|
||||||
Author(s): @kfswain, @ahg-g, @nirrozenbaum | ||||||
## Proposal Status | ||||||
***Draft*** | ||||||
|
||||||
## Summary | ||||||
The Scheduling Subsystem is a framework used to implement scheduling algorithms. High level definition [here](https://github.com/kubernetes-sigs/gateway-api-inference-extension/tree/main/docs/proposals/006-scheduler) & EPP Architecture [here](https://github.com/kubernetes-sigs/gateway-api-inference-extension/tree/main/docs/proposals/0683-epp-architecture-proposal). | ||||||
|
||||||
## Design Principles | ||||||
- The scheduler framework should act as an independent library, there should be no dependency on EPP packages defined outside of the scheduler | ||||||
- The *framework* should be agnostic to web protocols(such as HTTP), endpoint types (such as model servers), and K8s concepts. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
This is a good goal to strive for. Note that the use of HTTP headers to pass information around might not let us achieve it (from a "purist" point of view...). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I'm intentionally pushing any HTTP header context outside of the scheduler subsystem and into the
In the context of this subsystem, yes, endpoint it entirely agnostic to what the endpoint maps too, it is up to the system calling the scheduler to care about what the endpoint maps to. In fact, I'm considering having the scheduler system not be aware of IP/Port/Networking metadata, as: for the scope of the scheduler, a simple uniquely identifying string suffices for selection. What is done with that selection & how it's used in routing it out of scope of this component. That's my thinking anyway There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we may need to know IP address (and port) to encode the P/D information. The selection of P and D targets is known inside the scheduler and I don't think it should "leak" outside. While the primary endpoint is an agreed output and thus can be encoded as part of the EPP protocol with the gateway implementation, we need to be able to encode the secondary (or other) selection as HTTP headers or find a way to communicate it from Scheduler to |
||||||
- Opinons should be held by the plugins, not the framework | ||||||
kfswain marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
- The entry & exit points should be defined by the framework, acting as the API surface of the system | ||||||
- Multiple scheduling 'profiles' should be able to be ran for a single request. | ||||||
- They can be conditionally dependent on previous runs, or in parallel | ||||||
- Plugin state is managed by the plugin itself | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. at which point does "plugin state" become "system state"? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, this will be something we will need to tune. But to answer:
Yes, for now, the thinking is its the responsibility of the plugin to collect unique data; as that will make out of tree plugins easier to support. But I also have been toying with the argument of: It is entirely not the scheduler subsystems responsibility to collect & store data, and that should be handled by another system. But I worry that would tightly couple a data collection system to plugins too much. as plugins need some form of data to function properly. But a separate data store per plugin is also kind of an anti-pattern imo. Ultimately, I think this is a grey area and we probably need to support plugins having their own data store, but advise that a central datastore should be the way endpoint data is handled/stored There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Agree. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think three types of state will be sufficient:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ++. agreed. |
||||||
|
||||||
## Definitions | ||||||
- **Scheduling Framework** - The system created to allow for a pluggable scheduling algorithm. | ||||||
- **Scheduling Profile** - A named, specific set of Filter(s), Scorer(s), & Picker used to select endpoints. | ||||||
- **Scheduler** - An extensible implementation of a scheduling algorithm. Including logic to select Scheduling Profiles, the Scheduling Profiles themselves, & logic to interpret the result. | ||||||
- **Scheduling Cycle** - A single run of a Scheduler through the Scheduling Framework. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Scheduling Cycle - A single run of a Scheduler * Profile * |
||||||
- **Plugin** - Implementation of framework-defined interface(s) to add or extend logic across the framework. | ||||||
|
||||||
## Proposal | ||||||
|
||||||
The Scheduling System draws inspiration from the kube-schedulers pluggable system, though there are distinct differences in goals/usage. | ||||||
|
||||||
The Scheduling System can loosely be defined into 3 sections: | ||||||
- A *framework* to implement the system | ||||||
- The *interfaces* that a consumer can use to extend the system | ||||||
- A *configuration API* to define the Scheduler, Profile(s), & the plugins used within those profiles | ||||||
|
||||||
A sketch of the System, with extension points is here: | ||||||
<img src="./images/scheduler_subsystem.svg" alt="Scheduling Algorithm" width="1000" /> | ||||||
|
||||||
Describing the interface extension points & flow is the simplest way to convey the intent of what the framework should enable: | ||||||
|
||||||
### PreSchedule | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||
|
||||||
PreSchedule is the entry point into the scheduling cycle (called by the framework). PreSchedule, selects profiles conditionally based on: | ||||||
|
||||||
- Request data | ||||||
- Results | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Results of what? |
||||||
- Cycle State | ||||||
|
||||||
PreSchedule will be continuously called so long as profiles are returned; multiple profiles may be returned in a single call. Only a single PreSchedule function may be defined per scheduler. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. replace continuously with iteratively. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Q: should it also return some context for running the profiles? For example, can profiles be run in parallel or not, should the scheduler call into the plugin or not, etc. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
can update the readme to clarify, but the expectation would be that any profiles returned in a single I originally had a bool in the function signature to tell the framework that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I think this would lead to using one profile per call.
I prefer the explicit option as well. |
||||||
|
||||||
### Profile Cycle | ||||||
|
||||||
The profile cycle consists of 3 defined functions `Filter`, `Score`, & `Pick` | ||||||
|
||||||
*Profile Constraints* | ||||||
- A profile can have any number of `Filter` plugins registered (including zero) | ||||||
- A profile can have any number of `Score` plugins registered (including zero) | ||||||
- A profile MUST have exactly one `Pick` plugin registered | ||||||
|
||||||
|
||||||
#### Filter | ||||||
Filter runs before any scoring, and remove endpoints that are not fit for selection. The framework will return an error to the client if the endpoints are filtered to zero. | ||||||
|
||||||
#### Score | ||||||
Score applies a score to each remaining endpoint provided. Scorers SHOULD keep their score values in a normalized range: [0-1]. Any weighting should be added at the SchedulingProfile configuration level. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Separate issue: weights and range. Is it possible to define a scoring function that is evaluated to
I'd appreciate pointers to discussion/decisions relating to scoring. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Great questions. Many of these would be up to user implementation, since they can also implement the
I would advise against negative weights, and instead used fractional scores (we would need to change weights to float type to match)
The default picker would expect a higher score to imply better fit, yes.
Right, weights would be the way for a scheduling algo to give greater import to certain scorers over others. Which is why normalized score values from the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In kube-scheduler we simply used a range from 0-100, the higher the better the fit. The score evaluates the different backends from the perspective of a single scorer. Weights is the knob to determine how scores across plugins compare, this separation allows score plugins to implement their scoring algorithm independently from each other. Weights is a tunable parameter for the platform admin, but we need to offer defaults that work well out of the box (higher weights to prefix scores for example) |
||||||
|
||||||
#### Pick | ||||||
Picker selects the endpoint(s) from the provided list of scored endpoints. Picker MUST return, one endpoint at minimum. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the expected behavior (or - are there any assumptions) when more than one is returned? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, so that would be based on the PostSchedule/ResultAggregation implementation. We can document more of the expectations of the default implementation (i.e. they would be treated like fallback endpoints). But that might be documentation around that specific implementation, and not necessarily this interface. But open to other opinions here. |
||||||
|
||||||
|
||||||
### PostSchedule | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. rename to a descriptive name, for example ProcessProfileResults (as specified in the diagram in my last comment) |
||||||
PostSchedule recieves the output of the result(s) of the scheduling cycle(s) and makes sense of the data to be consumed by the calling system. | ||||||
|
||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added in the diagram in my last comment a "true" PostSchedule, that happens after scheduler returns, per Abdullah's comment in one of the open conversations. we can merge the two OR we can keep two extension points, one of |
||||||
### PostResponse | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This does not feel like a natural Scheduling plugin. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree with you. I really don't like including this in the scope of the scheduling system. But based on feedback, there is a desire for per-plugin datastore management as discussed in other comments. I would be very happy to remove this, but that gets back in to the fact that doing so may highly couple the data system to the scheduling system. Perhaps that is unavoidable. |
||||||
PostResponse is a special case extension that can optionally be implemented by a plugin that needs to augment its state based on response or request data. This should only be implemented for plugins that need to update state outside of the scheduling cycle. PostResponse is ran at the time of processing a response. | ||||||
Comment on lines
+73
to
+74
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we should specify that this is outside of the scheduler. |
||||||
|
||||||
## ConfigurationAPI | ||||||
TODO |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#names are egregiously long, but attempting to descibe custom logic within a name | ||
profileSelection: disagg-token-length | ||
schedulingResult: log-shadowbox-label-pd-result | ||
profiles: | ||
prefill: | ||
preschedule: | ||
- decode-prefix-cache-check | ||
filter: | ||
- is-prefill | ||
- has-required-accelerator | ||
score: | ||
- prefix-cache: 3 | ||
- latency-scorer: 2 | ||
selection: | ||
- best-score | ||
postschedule: | ||
- log-full-scores | ||
decode: | ||
filter: | ||
- is-decode | ||
score: | ||
- prefix-cache: 3 | ||
- kv-cache-util: 5 | ||
selection: | ||
- random-top-3 | ||
shadowbox-decode: | ||
filter: | ||
- is-decode | ||
- is-tpu | ||
score: | ||
- prefix-cache-v2: 4 | ||
- kv-cache-util: 1 | ||
selection: | ||
- random-top-3 |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,103 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/* | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Copyright 2025 The Kubernetes Authors. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Licensed under the Apache License, Version 2.0 (the "License"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
you may not use this file except in compliance with the License. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
You may obtain a copy of the License at | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
http://www.apache.org/licenses/LICENSE-2.0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Unless required by applicable law or agreed to in writing, software | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
distributed under the License is distributed on an "AS IS" BASIS, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
See the License for the specific language governing permissions and | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
limitations under the License. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
package framework | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"context" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
scheduling "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/types" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// READER NOTE: Currently CycleState is assumed to have appropriate request data rather that making a new object. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. as far as I understood, both @ahg-g and myself agree this should be passed as an argument and not in cycle state. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Plugin is the parent type for all the scheduling framework plugins. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
type Plugin interface { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Name() string | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
type Endpoint struct { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
State EndpointState | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Score float64 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
type EndpointState struct { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// storage is per Scheduling Cycle, and so has no thread-safe concerns. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thread-safe as long as we run all filters/scorers/picker sequentially on the same go routine. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ++, should make a note of that, that's how I would expect the framework to implement the scheduling cycle. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Agree within a single cycle, but what happens when more than one profile is returned? But returning more than one profile at a time you had specified that they can run in parallel... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed, I don't think there is a case that requires running profiles in "parallel". My preference is to return a single profile and a flag to indicate whether or not to pick and run another profile. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
storage map[string]any | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
type SchedulingResult struct { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
results map[string][]Endpoint | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+42
to
+44
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why do we need to wrap a map with a struct? |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Scheduler is the implementation of a... scheduler. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// The scheduler object is created at startup using the provided configuration. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
type Scheduler interface { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// PreSchedule selects scheduling profiles through the implemented | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// logic, and returns: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// - profiles - A subset of the registered scheduling profiles to be ran | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
PreSchedule(request map[string]any, data scheduling.CycleState, results map[string][]Endpoint) map[string]SchedulingProfile | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// PostSchedule recieves the output of the result(s) of the scheduling cycle(s) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// and makes sense of the data to be consumed by the calling system. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// For example: suppose you have 2 profiles ShadowBoxing Profile & Production Profile. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// PostSchedule would know to simply log the result of ShadowBoxing | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// profile, and do nothing else with it. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
PostSchedule(profileResults map[string][]Endpoint) SchedulingResult | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+46
to
+60
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. point (1) - I'd like to suggest using a more descriptive name. Additionally, this should be a plugin.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// SchedulingProfile is used to describe a profile that will | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// run for a given scheduling cycle. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
type SchedulingProfile struct { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Name of the profile. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Name string | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Filters lists all Filter plugins associated with this Profile. Filters | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// are optional. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Filters []Filter | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Scorers lists all Score plugins associated with this Profile. Scorers | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// are optional. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Scorers map[Scorer]int | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Picker returns the function that picks the endpoint(s). Picker is required. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Picker Picker | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Filter runs before any scoring, and remove endpoints that are not fit for | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// selection. The framework will return an error to the client if the endpoints | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// are filtered to zero. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
type Filter interface { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Plugin | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Filter(ctx context.Context, state scheduling.CycleState, endpoints []Endpoint) []Endpoint | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Scorer applies a score to each remaining endpoint provided. Scorers SHOULD | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// keep their score values in a normalized range: [0-1]. Any weighting should | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// be added at the SchedulingProfile configuration level. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
type Scorer interface { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Plugin | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Score(ctx context.Context, state scheduling.CycleState, endpoints []Endpoint) []Endpoint | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Picker selects the endpoint(s) from the provided list of scored endpoints. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Picker MUST return, one endpoint at minimum. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
type Picker interface { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Plugin | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Pick(ctx context.Context, state scheduling.CycleState, endpoints []Endpoint) []Endpoint | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
type PostResponse interface { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Plugin | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
PostResponse(ctx context.Context, request map[string]any, response map[string]any) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} |
Uh oh!
There was an error while loading. Please reload this page.