From 08652dbbf80b5ffd2cd35602484e3b57ce3ac210 Mon Sep 17 00:00:00 2001 From: Bowei Xu Date: Thu, 8 Mar 2018 11:19:24 -0800 Subject: [PATCH] CLI: Add list workers of tasklist (#597) * Add CLI to homepage readme * Add list worker info of tasklist * Adjust import order --- README.md | 4 ++++ tools/cli/README.md | 7 +++++++ tools/cli/app.go | 6 ++++++ tools/cli/commands.go | 39 +++++++++++++++++++++++++++++++++++ tools/cli/tasklist.go | 47 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 103 insertions(+) create mode 100644 tools/cli/tasklist.go diff --git a/README.md b/README.md index f3d75eeedc1..fcccbcbf9f6 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,10 @@ You can also [build and run](docker/README.md) the service using Docker. Try out the sample recipes [here](https://github.com/samarabbas/cadence-samples) to get started. +### Use CLI + +Try out [Cadence command-line tool](tools/cli/README.md) to perform various tasks on Cadence + ## Contributing We'd love your help in making Cadence great. Please review our [instructions](CONTRIBUTING.md). diff --git a/tools/cli/README.md b/tools/cli/README.md index 0d91e3e194c..e9c30e9ecd1 100644 --- a/tools/cli/README.md +++ b/tools/cli/README.md @@ -11,6 +11,7 @@ also start workflow, show workflow history, signal workflow ... and many other t Run `./cadence` to view help message. There are some top level commands and global options. Run `./cadence domain` to view help message about operations on domain Run `./cadence workflow` to view help message about operations on workflow +Run `./cadence tasklist` to view help message about operations on tasklist (`./cadence help`, `./cadence help [domain|workflow]` will also print help messages) **Note:** make sure you have cadence server running before using CLI @@ -58,6 +59,12 @@ and it takes a string as input, so there is the `-i '"cadence"'`. Single quote ` **Note:** you need to start worker so that workflow can make progress. (Run `make && ./bin/helloworld -m worker` in cadence-samples to start the worker) +- Show running workers of a tasklist +``` +./cadence tasklist desc --tl helloWorldGroup + +``` + - Start workflow: ``` ./cadence workflow start --tl helloWorldGroup --wt main.Workflow --et 60 -i '"cadence"' diff --git a/tools/cli/app.go b/tools/cli/app.go index 6428e7b1f7f..15a89a517e5 100644 --- a/tools/cli/app.go +++ b/tools/cli/app.go @@ -60,6 +60,12 @@ func NewCliApp() *cli.App { Usage: "Operate cadence workflow", Subcommands: newWorkflowCommands(), }, + { + Name: "tasklist", + Aliases: []string{"tl"}, + Usage: "Operate cadence tasklist", + Subcommands: newTaskListCommands(), + }, } // set builder if not customized diff --git a/tools/cli/commands.go b/tools/cli/commands.go index 2e0358f78a0..5306a8fca89 100644 --- a/tools/cli/commands.go +++ b/tools/cli/commands.go @@ -32,6 +32,7 @@ import ( "os" "runtime/debug" "strconv" + "strings" "time" "github.com/fatih/color" @@ -59,6 +60,8 @@ const ( FlagRunIDWithAlias = FlagRunID + ", rid, r" FlagTaskList = "tasklist" FlagTaskListWithAlias = FlagTaskList + ", tl" + FlagTaskListType = "tasklisttype" + FlagTaskListTypeWithAlias = FlagTaskListType + ", tlt" FlagWorkflowType = "workflow_type" FlagWorkflowTypeWithAlias = FlagWorkflowType + ", wt" FlagExecutionTimeout = "execution_timeout" @@ -693,6 +696,35 @@ func listClosedWorkflow(client client.Client, pageSize int, earliestTime, latest return response.Executions, response.NextPageToken } +// DescribeTaskList show pollers info of a given tasklist +func DescribeTaskList(c *cli.Context) { + wfClient := getWorkflowClient(c) + taskList := getRequiredOption(c, FlagTaskList) + taskListType := strToTaskListType(c.String(FlagTaskListType)) // default type is decision + + ctx, cancel := newContext() + defer cancel() + response, err := wfClient.DescribeTaskList(ctx, taskList, taskListType) + if err != nil { + ErrorAndExit("DescribeTaskList failed", err) + } + + pollers := response.Pollers + if len(pollers) == 0 { + fmt.Println(colorMagenta("No poller for tasklist: " + taskList)) + return + } + + table := tablewriter.NewWriter(os.Stdout) + table.SetBorder(false) + table.SetColumnSeparator("|") + table.Append([]string{"Poller Identity", "Last Access Time"}) + for _, poller := range pollers { + table.Append([]string{poller.GetIdentity(), convertTime(poller.GetLastAccessTime())}) + } + table.Render() +} + func getDomainClient(c *cli.Context) client.DomainClient { service, err := cBuilder.BuildServiceClient(c) if err != nil { @@ -772,6 +804,13 @@ func parseTime(timeStr string, defaultValue int64) int64 { return resultValue } +func strToTaskListType(str string) s.TaskListType { + if strings.ToLower(str) == "activity" { + return s.TaskListTypeActivity + } + return s.TaskListTypeDecision +} + func getPtrOrNilIfEmpty(value string) *string { if value == "" { return nil diff --git a/tools/cli/tasklist.go b/tools/cli/tasklist.go new file mode 100644 index 00000000000..12615d32cee --- /dev/null +++ b/tools/cli/tasklist.go @@ -0,0 +1,47 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package cli + +import "github.com/urfave/cli" + +func newTaskListCommands() []cli.Command { + return []cli.Command{ + { + Name: "describe", + Aliases: []string{"desc"}, + Usage: "Describe pollers info of tasklist", + Flags: []cli.Flag{ + cli.StringFlag{ + Name: FlagTaskListWithAlias, + Usage: "TaskList description", + }, + cli.StringFlag{ + Name: FlagTaskListTypeWithAlias, + Value: "decision", + Usage: "Optional TaskList type [decision|activity]", + }, + }, + Action: func(c *cli.Context) { + DescribeTaskList(c) + }, + }, + } +}