Skip to content

Commit

Permalink
add support for increment/decrement values in fly scale count (#3891)
Browse files Browse the repository at this point in the history
* add support for increment/decrement values in `fly scale count`
Use `fly scale count +n` or `fly scale count -- -n` to
increment or decrement count relative to the current count.
  • Loading branch information
wjordan authored Aug 29, 2024
1 parent 53a4387 commit 790bb3b
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 15 deletions.
36 changes: 25 additions & 11 deletions internal/command/scale/count.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,30 +93,44 @@ func runScaleCount(ctx context.Context) error {
return runMachinesScaleCount(ctx, appName, appConfig, groups, maxPerRegion)
}

func parseGroupCounts(args []string, defaultGroupName string) (map[string]int, error) {
groups := make(map[string]int)
type groupCount struct{ absolute, relative int }
type groupCounts map[string]groupCount

func parseGroupCounts(args []string, defaultGroupName string) (groupCounts, error) {
groups := make(groupCounts)
apply := func(group string, countStr string) error {
var count groupCount
countNum, err := strconv.Atoi(countStr)
if err != nil {
return err
}
if strings.HasPrefix(countStr, "+") || strings.HasPrefix(countStr, "-") {
if countNum == 0 {
return fmt.Errorf("invalid relative scale count: %v", countStr)
}
count.relative = countNum
} else {
count.absolute = countNum
}
groups[group] = count
return nil
}

// single numeric arg: fly scale count 3
if len(args) == 1 {
count, err := strconv.Atoi(args[0])
if err == nil {
groups[defaultGroupName] = count
}
_ = apply(defaultGroupName, args[0]) // fall-through on error
}

// group labels: fly scale web=X worker=Y
// group labels: fly scale count web=X worker=Y
if len(groups) < 1 {
for _, arg := range args {
parts := strings.Split(arg, "=")
if len(parts) != 2 {
return nil, fmt.Errorf("'%s' is not a valid process=count option", arg)
}
count, err := strconv.Atoi(parts[1])
if err != nil {
if err := apply(parts[0], parts[1]); err != nil {
return nil, err
}

groups[parts[0]] = count
}
}

Expand Down
15 changes: 11 additions & 4 deletions internal/command/scale/count_machines.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
"github.com/superfly/flyctl/iostreams"
)

func runMachinesScaleCount(ctx context.Context, appName string, appConfig *appconfig.Config, expectedGroupCounts map[string]int, maxPerRegion int) error {
func runMachinesScaleCount(ctx context.Context, appName string, appConfig *appconfig.Config, expectedGroupCounts groupCounts, maxPerRegion int) error {
io := iostreams.FromContext(ctx)
flapsClient := flapsutil.ClientFromContext(ctx)
ctx = appconfig.WithConfig(ctx, appConfig)
Expand Down Expand Up @@ -262,15 +262,22 @@ func (pi *planItem) MachineSize() string {
return ""
}

func computeActions(machines []*fly.Machine, expectedGroupCounts map[string]int, regions []string, maxPerRegion int, defaults *defaultValues) ([]*planItem, error) {
func computeActions(machines []*fly.Machine, expectedGroupCounts groupCounts, regions []string, maxPerRegion int, defaults *defaultValues) ([]*planItem, error) {
actions := make([]*planItem, 0)
seenGroups := make(map[string]bool)
machineGroups := lo.GroupBy(machines, func(m *fly.Machine) string {
return m.ProcessGroup()
})
expectedCounts := lo.MapValues(expectedGroupCounts, func(c groupCount, group string) int {
count := c.absolute
if c.relative != 0 {
count = len(machineGroups[group]) + c.relative
}
return max(count, 0)
})

for groupName, groupMachines := range machineGroups {
expected, ok := expectedGroupCounts[groupName]
expected, ok := expectedCounts[groupName]
// Ignore the group if it is not expected to change
if !ok {
continue
Expand Down Expand Up @@ -309,7 +316,7 @@ func computeActions(machines []*fly.Machine, expectedGroupCounts map[string]int,
}

// Fill in the groups without existing machines
for groupName, expected := range expectedGroupCounts {
for groupName, expected := range expectedCounts {
if seenGroups[groupName] {
continue
}
Expand Down

0 comments on commit 790bb3b

Please sign in to comment.