summaryrefslogtreecommitdiff
path: root/cmd/cli/workers.go
diff options
context:
space:
mode:
authorValery Piashchynski <[email protected]>2020-12-24 11:05:00 +0300
committerGitHub <[email protected]>2020-12-24 11:05:00 +0300
commit439c93225d7a9ebaf7cbf1010a54594b906f7d54 (patch)
treeadc7d78e28a9512cb1b1ba85cb4f19dec7d1323d /cmd/cli/workers.go
parent40b6c3169931a3fef62b649db19ff01dc685b7d4 (diff)
parent62ee1770cc233328300438ffd690ea1d8fc747bb (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.go118
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
+}