added first scheduler

This commit is contained in:
ston1th 2020-06-10 01:22:35 +02:00
commit 4158f7f946

52
node.go
View file

@ -12,6 +12,7 @@ var (
ErrNodesOffline = errors.New("one or more nodes are offline")
ErrNodesNotSearched = errors.New("one or more nodes could not be searched")
ErrEmptyID = errors.New("id is empty")
ErrUnschedulable = errors.New("no schedulable node found")
)
type NodeStatus string
@ -31,17 +32,25 @@ type Node struct {
MaxMem int64 `json:"maxmem"`
Disk int64 `json:"disk"`
MaxDisk int64 `json:"maxdisk"`
ServerList ServerList `json:"-"`
serverList ServerList `json:"-"`
}
func (n *Node) MemFreePercent() float64 {
func (n *Node) memFreePercent() float64 {
return float64(n.Mem) / float64(n.MaxMem) * 100
}
func (n *Node) memUsedPercent() float64 {
return float64(n.MaxMem-n.Mem) / float64(n.MaxMem) * 100
}
func (n *Node) weight() int {
return int(n.memUsedPercent()) + (len(n.serverList) * 10)
}
type NodeList []*Node
func (nl NodeList) sortByFreeMem() {
sort.Sort(memSorter(nl))
func (nl NodeList) sortByWeight() {
sort.Sort(weightSorter(nl))
}
func (nl *NodeList) remove(i int) {
@ -49,26 +58,28 @@ func (nl *NodeList) remove(i int) {
*nl = (*nl)[:len(*nl)-1]
}
func (nl *NodeList) Filter(filters ...NodeFilter) {
func (nl *NodeList) filter(filters ...NodeFilter) {
for _, f := range filters {
f(nl)
}
}
func (nl *NodeList) GetServerList(ctx context.Context, c *NodeClient) (err error) {
func (nl *NodeList) getServerList(ctx context.Context, c *NodeClient) (err error) {
for _, n := range *nl {
n.ServerList, err = c.ListServers(ctx, n)
n.serverList, err = c.ListServers(ctx, n)
if err != nil {
return
}
}
}
type memSorter NodeList
type weightSorter NodeList
func (m memSorter) Len() int { return len(m) }
func (m memSorter) Less(i, j int) bool { return m[i].MemFreePercent() < m[j].MemFreePercent() }
func (m memSorter) Swap(i, j int) { m[i], m[j] = m[j], m[i] }
func (s weightSorter) Len() int { return len(s) }
func (s weightSorter) Less(i, j int) bool {
return s.weight() < s[j].weight()
}
func (s weightSorter) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
type NodeFilter func(*NodeList)
@ -136,7 +147,7 @@ func FilterVMAntiAffinity(url string) NodeFilter {
return
}
for i, n := range *nl {
for _, s := range n.ServerList {
for _, s := range n.serverList {
if s.ID == id {
nl.remove(i)
return
@ -150,7 +161,22 @@ type NodeClient struct {
client *Client
}
func (c *NodeClient) Schedule(ctx context.Context) (n *Node, err error) {
func (c *NodeClient) Schedule(ctx context.Context, filters ...NodeFilter) (n *Node, err error) {
nl, err := c.List(ctx)
if err != nil {
return
}
err = nl.getServerList(ctx, c)
if err != nil {
return
}
nl.filter(filters)
nl.sortByWeight()
if len(nl) == 0 {
err = ErrUnschedulable
return
}
n = nl[0]
return
}