From 4158f7f9464d7af86610c4558bf7d50c999fefbc Mon Sep 17 00:00:00 2001 From: ston1th Date: Wed, 10 Jun 2020 01:22:35 +0200 Subject: [PATCH] added first scheduler --- node.go | 52 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/node.go b/node.go index e6b05a5..7a8f89e 100644 --- a/node.go +++ b/node.go @@ -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 }