-
Notifications
You must be signed in to change notification settings - Fork 42
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
CLI Refresh: workflow signal
command
#432
Conversation
…write-workflow-signal # Conflicts: # go.mod # go.sum # temporalcli/commands.gen.go # temporalcli/commands.workflow.go # temporalcli/commands.workflow_exec.go # temporalcli/commandsmd/commands.md
0819721
to
c27034f
Compare
temporalcli/commands_test.go
Outdated
lastFoundPieceIndex := -1 | ||
for _, piece := range pieces { | ||
if !strings.Contains(line, piece) { | ||
if index := strings.Index(line, piece); index > lastFoundPieceIndex { | ||
lastFoundPieceIndex = index | ||
} else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dandavison - here is update for forcing order
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great, thanks for adding that! This looks like it will allow the pieces to match in an overlapping way -- I think we need to set lastFoundPieceIndex
to the index of the end of piece
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's ok to be overlapping, it's still in order by start of piece
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it's clear to me that when users make a call like s.ContainsOnSameLine(out, "Namespace", "default")
they mean
there exists a line which contains 'Namespace' and 'default', in that order (not overlapping).
I've never seen a test framework that allows them to be overlapping or out of order. I do think that your s.ContainsOnSameLine(out, "Namespace", "default")
call is nice and readable -- nicer to read than a regexp assertion for this common case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated
// Default the reason if not set | ||
reason := s.Reason | ||
if reason == "" { | ||
username := "<unknown-user>" | ||
if u, err := user.Current(); err != nil && u.Username != "" { | ||
username = u.Username | ||
} | ||
reason = "Requested from CLI by " + username | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Current CLI requires reason to be set by user. UI defaults to something like Terminated from Web UI by [email protected]
, so we follow a similar format, but we just do "Requested" instead of specific verb (batch job carries its own timestamp info).
temporalcli/commands_test.go
Outdated
if !strings.Contains(line, piece) { | ||
if index := strings.Index(line, piece); index > lastEndIndex { | ||
lastEndIndex = index + len(piece) | ||
} else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ha, algorithms like this are hard to get right first time without unit tests! I suggest we use a regular-expression based implementation, i.e. form a regex by joining pieces
with whatever separator gives the separator semantics that we think callers will want in the common case. That way the behavior of the utility is clear to anyone who looks at the code, and they can use their own regex assertion if they want different behavior. I'd also be OK with deleting this utility and requiring callers to use a regex explicitly.
As it is it still has bugs. The most serious I'm seeing is that ContainsOnSameLine("a b a", "b", "a")
will fail, when it should pass.
But also ContainsOnSameLine("ab", "a", "b")
will fail (no gap between them) and yet ContainsOnSameLine("axb", "a", "b")
will pass.
And related to the first bug, ContainsOnSameLine("a a", "a", "a")
will fail.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is why I wanted it simple and ask users to use regex if they needed more instead of increase the rules of this little helper. I regret not sticking to the original simple/looser requirements. At this point I think we should just document the limits and tell people to use regex if they want.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original version allowed the pieces to be in any order and overlapping, which isn't appropriate for a test harness assertion utility.
What do you see as the downside of implementing ContainsOnSameLine
as a regex search for pieces
joined by something like .*
or .+
or .*\s.*
? However it's implemented, the resulting function will have some behavior, which we need to make clear to callers. A regex is the best way to make that clear to callers as I see it.
Or, as I mentioned above, we could just delete the utility and let callers decide on their regex.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you see as the downside of implementing ContainsOnSameLine as a regex search for pieces joined by something like .* or .+ or .\s.?
The continual requirements. "Can you strip colors too?", "Can you make it case insensitive?", "Can you make it only allow whole words instead of partial match?", "Can you allow this to work on adjacent lines instead of just one?", etc etc. "But it isn't appropriate for an stdout test harness utility to not strip out ANSI codes", "But it isn't appropriate for this test harness utility to not check whole words", etc. Each has their own opinion and it was just meant to be a little code reuse thing, but I didn't want to name it ContainsAnywhereOnSameLineInAnyOrderMayOverlap
.
Or, as I mentioned above, we could just delete the utility and let callers decide on their regex.
This may be best, but I still want some code reuse and I accept the limitations of the little helper.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The continual requirements. "Can you strip colors too?", "Can you make it case insensitive?", "Can you make it only allow whole words instead of partial match?", "Can you allow this to work on adjacent lines instead of just one?", etc etc. "But it isn't appropriate for an stdout test harness utility to not strip out ANSI codes", "But it isn't appropriate for this test harness utility to not check whole words", etc.
My suggestions that a string matching function should enforce order of the query terms and not allow overlapping matches are perfectly reasonable and uncontroversial. I'm not proposing them as optional extra enhancements; I'm saying that these are basic requirements of a utility that searches for a line containing certain substrings.
In any case, it's not appropriate to attempt to ridicule reviewer suggestions like that. If you think that the suggestions are reasonable but not how you want the function to behave, then that’s of course fine – in that case please just ask the other team members for their opinion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated to support regex-based match
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, that looks great to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
Not much to add.
Only thing I'm unsure of is if we want to print the success on non-json output via the logger to stderr.
Seems like the rest of the output for this command goes to stdout and if I want to grep for the job ID (yes some prefer that over jq), I have to pipe stderr which is a bit awkward and non-standard.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed, there are bugs in the test helper function that need fixing.
I will update the started-batch statement to be a stdout line instead of a log line EDIT: Updated |
return err | ||
} | ||
|
||
exec, batchReq, err := c.workflowExecOrBatch(cctx, c.Parent.Namespace, cl) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did this just happen to be the first command implemented for which batch was an option?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes
if err := startBatchJob(cctx, cl, batchReq); err != nil { | ||
return err | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe that the contract of workflowExecOrBatch
is such that one or other of the above conditions must be true, so I'd like the code not to appear to allow neither to be executed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this is leftover from previous code where it could return all nils when you declined the prompt, but I decided to change that to be an error and did not change this.
@@ -41,3 +95,77 @@ func (*TemporalWorkflowTraceCommand) run(*CommandContext, []string) error { | |||
func (*TemporalWorkflowUpdateCommand) run(*CommandContext, []string) error { | |||
return fmt.Errorf("TODO") | |||
} | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although it's a private function, it would be good to document this something like
This function guarantees that exactly one of the 3 returned values will be non-nil.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Concur
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK great, I can make these minor changes.
What was changed
Add support for
workflow signal
command. The functionality is mostly unchanged from current CLI, but the output may be different.Improvements over current CLI:
--reason
not required for batch (same default format as UI)