diff options
author | Valery Piashchynski <[email protected]> | 2020-12-24 11:05:00 +0300 |
---|---|---|
committer | GitHub <[email protected]> | 2020-12-24 11:05:00 +0300 |
commit | 439c93225d7a9ebaf7cbf1010a54594b906f7d54 (patch) | |
tree | adc7d78e28a9512cb1b1ba85cb4f19dec7d1323d /cmd/cli/workers.go | |
parent | 40b6c3169931a3fef62b649db19ff01dc685b7d4 (diff) | |
parent | 62ee1770cc233328300438ffd690ea1d8fc747bb (diff) |
Merge pull request #462 from spiral/feature/CLIv2.0.0-alpha29
feature/CLI
Diffstat (limited to 'cmd/cli/workers.go')
-rw-r--r-- | cmd/cli/workers.go | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/cmd/cli/workers.go b/cmd/cli/workers.go new file mode 100644 index 00000000..d34de40a --- /dev/null +++ b/cmd/cli/workers.go @@ -0,0 +1,118 @@ +package cli + +import ( + "fmt" + "log" + "net/rpc" + "os" + "os/signal" + "syscall" + "time" + + tm "github.com/buger/goterm" + "github.com/fatih/color" + "github.com/spf13/cobra" + "github.com/spiral/errors" + "github.com/spiral/roadrunner-plugins/informer" + "github.com/spiral/roadrunner/v2/tools" +) + +var ( + interactive bool +) + +const InformerList string = "informer.List" + +func init() { + workersCommand := &cobra.Command{ + Use: "workers", + Short: "Show information about active roadrunner workers", + RunE: workersHandler, + } + + workersCommand.Flags().BoolVarP( + &interactive, + "interactive", + "i", + false, + "render interactive workers table", + ) + + root.AddCommand(workersCommand) +} + +func workersHandler(cmd *cobra.Command, args []string) error { + const op = errors.Op("workers handler") + // get RPC client + client, err := RPCClient() + if err != nil { + return err + } + defer func() { + err := client.Close() + if err != nil { + log.Printf("error when closing RPCClient: error %v", err) + } + }() + + var plugins []string + // assume user wants to show workers from particular plugin + if len(args) != 0 { + plugins = args + } else { + err = client.Call(InformerList, true, &plugins) + if err != nil { + return errors.E(op, err) + } + } + + if !interactive { + return showWorkers(plugins, client) + } + + // https://golang.org/pkg/os/signal/#Notify + // should be of buffer size at least 1 + c := make(chan os.Signal, 1) + signal.Notify(c, os.Interrupt, syscall.SIGTERM, syscall.SIGINT) + + tm.Clear() + tt := time.NewTicker(time.Second) + defer tt.Stop() + for { + select { + case <-c: + return nil + case <-tt.C: + tm.MoveCursor(1, 1) + err := showWorkers(plugins, client) + if err != nil { + return errors.E(op, err) + } + tm.Flush() + } + } +} + +func showWorkers(plugins []string, client *rpc.Client) error { + for _, plugin := range plugins { + list := &informer.WorkerList{} + err := client.Call("informer.Workers", plugin, &list) + if err != nil { + return err + } + + // it's a golang :) + ps := make([]tools.ProcessState, len(list.Workers)) + for i := 0; i < len(list.Workers); i++ { + ps[i].Created = list.Workers[i].Created + ps[i].NumJobs = list.Workers[i].NumJobs + ps[i].MemoryUsage = list.Workers[i].MemoryUsage + ps[i].Pid = list.Workers[i].Pid + ps[i].Status = list.Workers[i].Status + } + + fmt.Printf("Workers of [%s]:\n", color.HiYellowString(plugin)) + tools.WorkerTable(os.Stdout, ps).Render() + } + return nil +} |