Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cadence CLI #577

Merged
merged 1 commit into from
Mar 2, 2018
Merged

Cadence CLI #577

merged 1 commit into from
Mar 2, 2018

Conversation

vancexu
Copy link
Contributor

@vancexu vancexu commented Feb 23, 2018

command line tool for users to perform common tasks with cadence, see readme for details.
Tests will be done in separate PR

@coveralls
Copy link

coveralls commented Feb 23, 2018

Coverage Status

Coverage decreased (-3.0004%) to 64.345% when pulling b7f91d8 on cli into 5c6cb08 on master.

data = e.WorkflowExecutionTerminatedEventAttributes

default:
data = e
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this list of events is not complete, at least missing the child workflow events

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, added all

}

// WorkflowClientBuilderInterface is an interface to build client to cadence service
type WorkflowClientBuilderInterface interface {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this file here? Where is it being used? Can't find any references in the diff.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I previously thought common might be a good place, and later playground or other apps can use it. But now I think it might be better just put everything in cli folder for now, so changed.
This interface is used in "commands.go", and I need it so that I can have a customized builder used internal. See update comments in the file.

app.Flags = []cli.Flag{
cli.StringFlag{
Name: FlagAddressWithAlias,
Value: "",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we have default value of 127.0.0.1:7933, it is not the case?

Copy link
Contributor Author

@vancexu vancexu Feb 27, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Default localHostPort is 127.0.0.1:7933. I put empty string here because it is easier for processing.

tools/cli/app.go Outdated
cli.BoolFlag{
Name: FlagCustomizeBuilderWithAlias,
Usage: "customize builder function or default",
EnvVar: "CADENCE_CUSTOMIZED_BUILDER",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this flag is confusing. How is user suppose to use this flag?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree it is confusing, removed.

var colorGreen func(i ...interface{}) string

func init() {
colorRed = color.New(color.FgRed).SprintFunc()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you assign the value when you declare the variables so we don't need this init()?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed

}

// cBuilder is used to create cadence clients if user want to provide customized builder
var cBuilder WorkflowClientBuilderInterface

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why do we need this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is necessary for customized builder. Internally, we have special tag like ENV and additional processing when creating builder. By implementing these interfaces and inject with SetBuilder, we can achieve customized builder. This is transparent to CLI user.

}

func newContextForLongPoll() (context.Context, context.CancelFunc) {
return context.WithTimeout(context.Background(), time.Minute*2)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to let user specify timeout for this? (Make it optional, and default to 2 minutes.) For example, what if the workflow takes longer than 2 minutes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, changed.

@vancexu vancexu mentioned this pull request Feb 26, 2018
- You should see an executable `cadence-cli`

## Quick Start
Run `./cadence-cli` to view help message. There are some top level commands and global options.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is it cadence-cli? The current one is just "cadence".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed to cadence

- You should see an executable `cadence-cli`

## Quick Start
Run `./cadence-cli` to view help message. There are some top level commands and global options.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should also reply to
cadence help
cadence help domain
cadence help workflow

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's rename cadence to cadence-server and cadence-cli to cadence then

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

*Note:* make sure you have cadence server running before using CLI

### Domain operation examples
- Register a new domain named "samples-domain":
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should you reference DOMAIN environment here?
Should we add support for .cadence file that is looked in the parent directories that contains variables like domain?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good suggestion, I will add DOMAIN env here also.
File support will be done as a feature, together with cache workflow_id and run_id

```
- View "samples-domain" details:
```
./cadence-cli --domain samples-domain domain describe
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why we have "show" for workflow and "describe" for domain?

Copy link
Contributor Author

@vancexu vancexu Feb 27, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think "workflow describe" is a little bit confusing which looks like describe detail info of workflow such as workflow type, arguments, wid, runid etc, but workflow show is showing history.

./cadence-cli --domain samples-domain workflow start --tl helloWorldGroup --wt main.Workflow --et 60 --dt 10 -i '"vancexu"'

# see more options for workflow start
./cadence-cli --domain samples-domain workflow start -h
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be
cadence workflow start help

It think
cadence help

should say to run
cadence workflow help
and
cadence domain help
And cadence workflow help should ask to run
cadence workflow start help

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, cadence workflow start help won't work because there is no help subsubcommands, but only --help or -h command options.

When view help of cadence workflow it will show below:

NAME:
   cadence workflow - Operate cadence workflow

USAGE:
   cadence workflow command [command options] [arguments...]

COMMANDS:
     show             show workflow history
     start            start a new workflow execution
     run              start a new workflow execution and get workflow progress
     cancel, c        cancel a workflow execution
     signal, s        signal a workflow execution
     terminate, term  terminate a new workflow execution
     list             list open or closed workflow executions
     query            query workflow execution

OPTIONS:
   --help, -h  show help

the usage will indicate how the help option can be used


# for workflow with multiple input, seperate each json with space/newline like
./cadence-cli --domain samples-domain workflow start --tl helloWorldGroup --wt main.WorkflowWith3Args --et 60 --dt 10 -i '"your_input_string" 123 {"Name":"my-string", "Age":12345}'
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we just make it a single json list?
["your_input_string", 123, {"Name":"my-string", "Age":12345}]
For single value do not require the list wrapper.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately we cannot.
Because using your proposal there is no way to tell if ["your_input_string", 123, {"Name":"my-string", "Age":12345}] input is 1 list argument or 3 arguments.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could say that list always defaults to the list of arguments. If they indeed want to specify list as a single argument (which is very rare) then they have to pass list of lists:
[[...]].

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is it resolved?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After discussion, we decide to stick with using spaces/newlines separate json, instead of the proposed using list.

./cadence-cli --domain samples-domain workflow start --tl helloWorldGroup --wt main.WorkflowWith3Args --et 60 --dt 10 -i '"your_input_string" 123 {"Name":"my-string", "Age":12345}'
```

- Run workflow and see the progress
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this one should come before start as most developers should use it during development. I think you also want to expand on what "run" means in this context and what benefits over start it has.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed

# then you can just
./cadence-cli domain desc
./cadence-cli workflow list
./cadence-cli workflow show -w greetings_38a9e481-a00c-433a-b1ff-b6f67536efd8
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make -w optional after show? Just workflow show UUID?

Copy link
Contributor Author

@vancexu vancexu Feb 27, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the cli framework we currently use, it would be a little bit tricky to achieve this requirement. Because show commands also accepts other optional arguments.
Instead, I propose to add new command like showid <wid> as a separate command which takes only wid and have no other arguments to achieve this. what do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it is indeed that hard then showid is OK.

Copy link
Contributor Author

@vancexu vancexu Mar 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, added showid as a shortcut of show -w <wid> -r <rid>

// Usually default WorkflowClientBuilder is enough for development purpose, but
// user can still customized builder by implementing this interface, and call SetBulder after initialize cli.
// The customized builder may have more processing on Env, Address and other info.
type WorkflowClientBuilderInterface interface {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought we talked about this interface, and decided that it only need one method:
CreateServiceClient(ctx *cli.Context). Or am I missing something?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed, I missed one part previously. Thanks


- Run workflow: Start a workflow and see it's progress
```
./cadence workflow run --tl helloWorldGroup --wt main.Workflow --et 60 --dt 10 -i '"cadence"'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's default decision task timeout to something like 5 seconds and do not require it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, default 10 sec

### Workflow operation examples
(The following examples assume you already export CADENCE_CLI_DOMAIN environment variable as Tips above)

- Run workflow: Start a workflow and see it's progress
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add that this command doesn't finish until workflow completes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

- List open or closed workflow executions
```
./cadence workflow list
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about query?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added. Need to add samples to make it looks better later


# for workflow with multiple input, seperate each json with space/newline like
./cadence-cli --domain samples-domain workflow start --tl helloWorldGroup --wt main.WorkflowWith3Args --et 60 --dt 10 -i '"your_input_string" 123 {"Name":"my-string", "Age":12345}'
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could say that list always defaults to the list of arguments. If they indeed want to specify list as a single argument (which is very rare) then they have to pass list of lists:
[[...]].

)

// Start using this CLI tool with command
// `./cadence-cli` to show help message

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update the comments to remove -cli.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

type WorkflowClientBuilder struct {
hostPort string
dispatcher *yarpc.Dispatcher
Logger *zap.Logger

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this field public? Also, does the WorkflowClientBuilder needs to be public?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, changed Logger to logger.
WorkflowClientBuilder is needed, otherwise lint complain on NewBuilder function.

func main() {
app := cli.NewCliApp()

logger, err := zap.NewDevelopment()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we not make this logger a required argument to NewBuilder()? It could create a default inside that builder. Just want to keep code here to be minimal.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

if err != nil {
panic(err)
}
cli.SetBuilder(cli.NewBuilder(logger))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would even make this call optional and use cli.NewBuilder() if it is not set.
Actually, I would check the builder inside the cli.NewCliApp() and set it to the default value if it is not set yet. So in internal version, you can call the cli.SetBuilder() before cli.NewCliApp().

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sense I like it. Updated.

- Query workflow execution
```
# use build-in query type "__stack_trace" which is supported by cadence client library
./cadence workflow query -w <wid> -r <rid>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about
cadence workflow stack -w ...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think query at least link me with QueryWorkflow of cadence-client, no sure why you propose stack?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because if you don't specify query type you default to stack which is confusing. I would require query type, but provide separate command "stack" which would execute query type "__stack_trace" which is hard to remember.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added stack command


- Start workflow:
```
./cadence workflow start --tl helloWorldGroup --wt main.Workflow --et 60 --dt 10 -i '"cadence"'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would change ./cadence to cadence in all these samples. In most cases it would be installed though brew or be somewhere in the PATH.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this readme, I think ./cadence is better because reader can easily understand it is the executable after running make, and "advanced player" can obviously use PATH and replace it to whatever they what.
Directly put cadence instead of ./cadence will confuse beginner, if I don't have instructions on how to set PATH or use brew. And for the simplicity of this readme, I don't want to include those.

./cadence workflow query -w <wid> -r <rid> --qt <query-type>
```

- Signal, cancel, terminate workflow
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have the open activities visibility query. Where is it?
Also we have list of workers connected to a task list. Where is it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Create #588 and will work on separate pull request.

Copy link

@yiminc-zz yiminc-zz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code lgtm.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants