chore: init scheduler entities

This commit is contained in:
Pavel Sviderski
2025-04-15 22:30:03 +10:00
parent 7705db2c4f
commit 000a8a1d3e
3 changed files with 138 additions and 0 deletions
+37
View File
@@ -0,0 +1,37 @@
package scheduler
import (
"strings"
"github.com/psviderski/uncloud/pkg/api"
)
// Constraint is the base interface for all scheduling constraints.
type Constraint interface {
// Evaluate determines if a machine satisfies the constraint.
Evaluate(machine *Machine) bool
// Description returns a human-readable description of the constraint.
Description() string
}
func constraintsFromSpec(spec api.ServiceSpec) []Constraint {
return []Constraint{}
}
type PlacementConstraint struct {
Machines []string
}
func (c *PlacementConstraint) Evaluate(machine *Machine) bool {
for _, nameOrID := range c.Machines {
if machine.Info.Id == nameOrID || machine.Info.Name == nameOrID {
return true
}
}
return false
}
func (c *PlacementConstraint) Description() string {
return "Placement constraint by machines: " + strings.Join(c.Machines, ", ")
}
+50
View File
@@ -0,0 +1,50 @@
package scheduler
import (
"context"
"fmt"
"github.com/docker/docker/api/types/volume"
"github.com/psviderski/uncloud/internal/machine/api/pb"
"github.com/psviderski/uncloud/pkg/api"
)
type Client interface {
api.MachineClient
api.VolumeClient
}
type Machine struct {
Info *pb.MachineInfo
Volumes []volume.Volume
}
// InspectMachines retrieves the list of available machines and their details required for scheduling purposes.
// TODO: refactor to get all the details in one broadcast call to machine API.
func InspectMachines(ctx context.Context, cli Client) ([]*Machine, error) {
machineMembers, err := cli.ListMachines(ctx, &api.MachineFilter{Available: true})
if err != nil {
return nil, fmt.Errorf("list machines: %w", err)
}
volumes, err := cli.ListVolumes(ctx, nil)
if err != nil {
return nil, fmt.Errorf("list volumes: %w", err)
}
var machines []*Machine
for _, m := range machineMembers {
machine := &Machine{
Info: m.Machine,
}
for _, v := range volumes {
if v.MachineID == m.Machine.Id {
machine.Volumes = append(machine.Volumes, v.Volume)
}
}
machines = append(machines, machine)
}
return machines, nil
}
+51
View File
@@ -0,0 +1,51 @@
package scheduler
import (
"errors"
"github.com/psviderski/uncloud/internal/machine/api/pb"
"github.com/psviderski/uncloud/pkg/api"
)
type ServiceScheduler struct {
machines []*Machine
spec api.ServiceSpec
constraints []Constraint
}
func NewServiceScheduler(machines []*Machine, spec api.ServiceSpec, constraints []Constraint) *ServiceScheduler {
specConstraints := constraintsFromSpec(spec)
specConstraints = append(specConstraints, constraints...)
return &ServiceScheduler{
machines: machines,
spec: spec,
constraints: specConstraints,
}
}
func (s *ServiceScheduler) AvailableMachines() ([]*Machine, error) {
var available []*Machine
for _, machine := range s.machines {
if s.evaluateConstraints(machine) {
available = append(available, machine)
}
}
if len(available) == 0 {
return nil, errors.New("no machines available that satisfy all constraints")
}
return available, nil
}
func (s *ServiceScheduler) evaluateConstraints(machine *Machine) bool {
for _, c := range s.constraints {
if !c.Evaluate(machine) {
return false
}
}
return true
}
func (s *ServiceScheduler) ScheduleContainer() ([]*pb.MachineInfo, error) {
return nil, errors.New("not implemented")
}