|
1 | 1 | package client |
2 | 2 |
|
3 | | -import "strconv" |
| 3 | +import ( |
| 4 | + "errors" |
| 5 | + "math" |
| 6 | + "strconv" |
| 7 | + "strings" |
| 8 | +) |
4 | 9 |
|
5 | 10 | // Scale creates or destroys units to match the desired number |
6 | | -func (c *FleetClient) Scale(component string, requested int) (err error) { |
7 | | - for { |
8 | | - components, err := c.Units(component) |
9 | | - if err != nil { |
| 11 | +func (c *FleetClient) Scale(component string, requested int) error { |
| 12 | + if requested < 0 { |
| 13 | + return errors.New("cannot scale below 0") |
| 14 | + } |
| 15 | + // check how many currently exist |
| 16 | + components, err := c.Units(component) |
| 17 | + if err != nil { |
| 18 | + // skip checking the first time; we just want a tally |
| 19 | + if !strings.Contains(err.Error(), "could not find unit") { |
10 | 20 | return err |
11 | 21 | } |
12 | | - if len(components) == requested { |
13 | | - break |
14 | | - } |
15 | | - if len(components) < requested { |
16 | | - num, err := c.nextUnit(component) |
17 | | - if err != nil { |
18 | | - return err |
19 | | - } |
20 | | - if err = c.Create([]string{component + "@" + strconv.Itoa(num)}); err != nil { |
21 | | - return err |
22 | | - } |
23 | | - continue |
| 22 | + } |
| 23 | + |
| 24 | + timesToScale := int(math.Abs(float64(requested - len(components)))) |
| 25 | + if requested-len(components) > 0 { |
| 26 | + return scaleUp(c, component, len(components), timesToScale) |
| 27 | + } else { |
| 28 | + return scaleDown(c, component, len(components), timesToScale) |
| 29 | + } |
| 30 | +} |
| 31 | + |
| 32 | +func scaleUp(c *FleetClient, component string, numExistingContainers, numTimesToScale int) error { |
| 33 | + for i := 0; i < numTimesToScale; i++ { |
| 34 | + if err := c.Create([]string{component + "@" + strconv.Itoa(numExistingContainers+i+1)}); err != nil { |
| 35 | + return err |
24 | 36 | } |
25 | | - if len(components) > requested { |
26 | | - num, err := c.lastUnit(component) |
27 | | - if err != nil { |
28 | | - return err |
29 | | - } |
30 | | - if err = c.Destroy([]string{component + "@" + strconv.Itoa(num)}); err != nil { |
31 | | - return err |
32 | | - } |
33 | | - continue |
| 37 | + } |
| 38 | + return nil |
| 39 | +} |
| 40 | + |
| 41 | +func scaleDown(c *FleetClient, component string, numExistingContainers, numTimesToScale int) error { |
| 42 | + for i := 0; i < numTimesToScale; i++ { |
| 43 | + if err := c.Destroy([]string{component + "@" + strconv.Itoa(numExistingContainers-i)}); err != nil { |
| 44 | + return err |
34 | 45 | } |
35 | 46 | } |
36 | | - return |
| 47 | + return nil |
37 | 48 | } |
0 commit comments