summaryrefslogtreecommitdiff
path: root/cmd/cli/reset.go
blob: 504d88ad89833e993ed98bdbb1cd21217ca72002 (plain)
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package cli

import (
	"fmt"
	"sync"

	"github.com/fatih/color"
	"github.com/mattn/go-runewidth"
	"github.com/spf13/cobra"
	"github.com/spiral/errors"
	"github.com/vbauerster/mpb/v5"
	"github.com/vbauerster/mpb/v5/decor"
)

// List is the resetter.List RPC method
const List string = "resetter.List"

// Reset is the resetter.Reset RPC method
const Reset string = "resetter.Reset"

func init() {
	root.AddCommand(&cobra.Command{
		Use:   "reset",
		Short: "Reset workers of all or specific RoadRunner service",
		RunE:  resetHandler,
	})
}

func resetHandler(cmd *cobra.Command, args []string) error {
	const op = errors.Op("reset handler")
	client, err := RPCClient()
	if err != nil {
		return err
	}
	defer func() {
		_ = client.Close()
	}()

	var services []string
	if len(args) != 0 {
		services = args
	} else {
		err = client.Call(List, true, &services)
		if err != nil {
			return errors.E(op, err)
		}
	}

	var wg sync.WaitGroup
	pr := mpb.New(mpb.WithWaitGroup(&wg), mpb.WithWidth(6))
	wg.Add(len(services))

	for _, service := range services {
		var (
			bar    *mpb.Bar
			name   = runewidth.FillRight(fmt.Sprintf("Resetting plugin: [%s]", color.HiYellowString(service)), 27)
			result = make(chan interface{})
		)

		bar = pr.AddSpinner(
			1,
			mpb.SpinnerOnMiddle,
			mpb.SpinnerStyle([]string{"∙∙∙", "●∙∙", "∙●∙", "∙∙●", "∙∙∙"}),
			mpb.PrependDecorators(decor.Name(name)),
			mpb.AppendDecorators(onComplete(result)),
		)

		// simulating some work
		go func(service string, result chan interface{}) {
			defer wg.Done()
			defer bar.Increment()

			var done bool
			err = client.Call(Reset, service, &done)
			if err != nil {
				result <- errors.E(op, err)
				return
			}
			result <- nil
		}(service, result)
	}

	pr.Wait()
	return nil
}

func onComplete(result chan interface{}) decor.Decorator {
	var (
		msg = ""
		fn  = func(s decor.Statistics) string {
			select {
			case r := <-result:
				if err, ok := r.(error); ok {
					msg = color.HiRedString(err.Error())
					return msg
				}

				msg = color.HiGreenString("done")
				return msg
			default:
				return msg
			}
		}
	)

	return decor.Any(fn)
}