forked from vmware-archive/atc
/
placement.go
63 lines (49 loc) · 1.47 KB
/
placement.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package worker
import (
"math/rand"
"time"
)
type ContainerPlacementStrategy interface {
Choose([]Worker, ContainerSpec) (Worker, error)
}
type VolumeLocalityPlacementStrategy struct {
rand *rand.Rand
}
func NewVolumeLocalityPlacementStrategy() ContainerPlacementStrategy {
return &VolumeLocalityPlacementStrategy{
rand: rand.New(rand.NewSource(time.Now().UnixNano())),
}
}
func (strategy *VolumeLocalityPlacementStrategy) Choose(workers []Worker, spec ContainerSpec) (Worker, error) {
workersByCount := map[int][]Worker{}
var highestCount int
for _, w := range workers {
candidateInputCount := 0
for _, inputSource := range spec.Inputs {
_, found, err := inputSource.Source().VolumeOn(w)
if err != nil {
return nil, err
}
if found {
candidateInputCount++
}
}
workersByCount[candidateInputCount] = append(workersByCount[candidateInputCount], w)
if candidateInputCount >= highestCount {
highestCount = candidateInputCount
}
}
highestLocalityWorkers := workersByCount[highestCount]
return highestLocalityWorkers[strategy.rand.Intn(len(highestLocalityWorkers))], nil
}
type RandomPlacementStrategy struct {
rand *rand.Rand
}
func NewRandomPlacementStrategy() ContainerPlacementStrategy {
return &RandomPlacementStrategy{
rand: rand.New(rand.NewSource(time.Now().UnixNano())),
}
}
func (strategy *RandomPlacementStrategy) Choose(workers []Worker, spec ContainerSpec) (Worker, error) {
return workers[strategy.rand.Intn(len(workers))], nil
}