github.com/technosophos/deis@v1.7.1-0.20150915173815-f9005256004b/deisctl/backend/fleet/scale.go (about) 1 package fleet 2 3 import ( 4 "fmt" 5 "io" 6 "math" 7 "strconv" 8 "strings" 9 "sync" 10 ) 11 12 // Scale creates or destroys units to match the desired number 13 func (c *FleetClient) Scale( 14 component string, requested int, wg *sync.WaitGroup, out, ew io.Writer) { 15 16 if requested < 0 { 17 fmt.Fprintln(ew, "cannot scale below 0") 18 return 19 } 20 // check how many currently exist 21 components, err := c.Units(component) 22 if err != nil { 23 // skip checking the first time; we just want a tally 24 if !strings.Contains(err.Error(), "could not find unit") { 25 fmt.Fprintln(ew, err.Error()) 26 return 27 } 28 } 29 30 timesToScale := int(math.Abs(float64(requested - len(components)))) 31 switch { 32 case timesToScale == 0: 33 return 34 case requested-len(components) > 0: 35 c.scaleUp(component, len(components), timesToScale, wg, out, ew) 36 default: 37 c.scaleDown(component, len(components), timesToScale, wg, out, ew) 38 } 39 } 40 41 func (c *FleetClient) scaleUp(component string, numExistingContainers, numTimesToScale int, 42 wg *sync.WaitGroup, out, ew io.Writer) { 43 for i := 0; i < numTimesToScale; i++ { 44 target := component + "@" + strconv.Itoa(numExistingContainers+i+1) 45 c.Create([]string{target}, wg, out, ew) 46 } 47 wg.Wait() 48 for i := 0; i < numTimesToScale; i++ { 49 target := component + "@" + strconv.Itoa(numExistingContainers+i+1) 50 c.Start([]string{target}, wg, out, ew) 51 } 52 } 53 54 func (c *FleetClient) scaleDown(component string, numExistingContainers, numTimesToScale int, 55 wg *sync.WaitGroup, out, ew io.Writer) { 56 for i := 0; i < numTimesToScale; i++ { 57 target := component + "@" + strconv.Itoa(numExistingContainers-i) 58 c.Destroy([]string{target}, wg, out, ew) 59 } 60 }