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

Implement activity commands #445

Merged
merged 3 commits into from
Feb 12, 2024

Conversation

dandavison
Copy link
Contributor

@dandavison dandavison commented Feb 12, 2024

What was changed

Implement temporal activity fail and temporal activity complete

How was this tested

  • PR includes end-to-end tests
  • I modified samples-python:hello/hello_activity.py to sleep for a long time in the activity, issued CLI commands (examples below), and confirmed results in web UI.
commit 5519021cac3a1d0b9818d903882e0e053ad3df8b (HEAD -> update-reapply)
Author: Dan Davison <dan.davison@temporal.io>
Date:   Mon Feb 12 18:02:34 2024 -0500

    Test cli activity commands

diff --git a/hello/hello_activity.py b/hello/hello_activity.py
index 6615b55..a8a8e54 100644
--- a/hello/hello_activity.py
+++ b/hello/hello_activity.py
@@ -21,6 +21,7 @@ class ComposeGreetingInput:
 @activity.defn
 async def compose_greeting(input: ComposeGreetingInput) -> str:
     activity.logger.info("Running activity with parameter %s" % input)
+    await asyncio.sleep(0xFFFFFFFF)
     return f"{input.greeting}, {input.name}!"
 
 
@@ -33,7 +34,8 @@ class GreetingWorkflow:
         return await workflow.execute_activity(
             compose_greeting,
             ComposeGreetingInput("Hello", name),
-            start_to_close_timeout=timedelta(seconds=10),
+            start_to_close_timeout=timedelta(seconds=0xFFFFFFFF),
+            activity_id="MyActivityId",
         )

Example commands tested

temporal-new activity complete --activity-id MyActivityId --workflow-id MyWorkflowId --result '{"resultkey": "resultval"}' --identity 'MyIdentity' --run-id e592b7a1-a15d-4de1-83b4-32ec070706fa
temporal-new activity fail --activity-id MyActivityId --workflow-id MyWorkflowId --detail '{"detailkey": "detailval"}' --run-id d9049fc2-ad6c-4f3e-9f04-52b287a7e913 --reason 'top-level-reason' --identity 'MyIdentity'

Copy link
Member

@cretz cretz left a comment

Choose a reason for hiding this comment

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

Some notes for now and future, but nothing blocking. The existing CLI sure was inconsistent/unclean with these two commands.

@@ -57,6 +57,43 @@ This document has a specific structure used by a parser. Here are the rules:
* `--color` (string-enum) - Set coloring. Options: always, never, auto. Default: auto.
* `--no-json-shorthand-payloads` (bool) - Always all payloads as raw payloads even if they are JSON.

### temporal activity: Complete or fail an activity.

Copy link
Member

@cretz cretz Feb 12, 2024

Choose a reason for hiding this comment

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

Suggested change
Activity commands operate on [Activity Executions](/concepts/what-is-an-activity-execution).
Activity commands follow this syntax:
`temporal activity [command] [command options]`

Just stole it from old CLI, but I guess not required (we hope to come back and clean these)

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, I'm not in love with that text from the old CLI. I think the help output is pretty clear as-is:

$ temporal activity -h
Complete or fail an activity.

Usage:
  temporal activity [command]

Available Commands:
  complete    Complete an activity.
  fail        Fail an activity.

and these Markdown links [Activity Executions](/concepts/what-is-an-activity-execution) don't link to a valid target (unless I'm missing something?)

Copy link
Member

Choose a reason for hiding this comment

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

Not missing anything, I too am not a fan, but I was just leaving many docs things as is to come back and be cleaned up later. Can just leave off too.

#### Options

* `--activity-id` (string) - The Activity to be completed. Required.
* `--identity` (string) - Identity of operator.
Copy link
Member

Choose a reason for hiding this comment

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

Previous CLI required this, but I am ok not requiring it


* `--activity-id` (string) - The Activity to be completed. Required.
* `--identity` (string) - Identity of operator.
* `--result` (string) - The result with which to complete the Activity (JSON). Required.
Copy link
Member

Choose a reason for hiding this comment

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

This works for me to meet parity. There are a few things we may want in the future to be as robust as --input for workflows:

  • --result as a string[] to accept multiple results
  • --result-file to accept files instead of strings
  • --result-meta to support payload metadata
  • --result-base64 bool to support base64 binary strings

I wonder if we should create an issue here (same for --detail on failure)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

Not sure this deserves its own file but meh

Copy link
Contributor Author

@dandavison dandavison Feb 12, 2024

Choose a reason for hiding this comment

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

Yeah, I wasn't sure how people would like the code arranged. Where would you put it out of interest?

Copy link
Member

Choose a reason for hiding this comment

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

Probably client, but it doesn't matter. As the utils grow we can move/consolidate as needed

"go.temporal.io/api/common/v1"
)

func CreatePayloads(data [][]byte, metadata map[string][]byte, isBase64 bool) (*common.Payloads, error) {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
func CreatePayloads(data [][]byte, metadata map[string][]byte, isBase64 bool) (*common.Payloads, error) {
func createPayloads(data [][]byte, metadata map[string][]byte, isBase64 bool) (*common.Payloads, error) {

Probably don't need to export (though it doesn't really matter in the context of an application vs a library so there's no rules here, so nothing required to change)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK thanks, my Go style is a work-in-progress... when I uppercased it I was thinking that I was working in a separate "util" package from the main commands, but as you point out that's not the case.

#### Options

* `--activity-id` (string) - The Activity to be completed. Required.
* `--identity` (string) - Identity of operator.
Copy link
Member

Choose a reason for hiding this comment

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

It was a bit inconsistent for us to have our CLI accept identity here but not on other commands like start workflow. I wonder if we should accept --identity higher up.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed; I'd like consistency across all protos that have an identity field. I was just going for parity here.

return err
}

_, err = cl.WorkflowService().RespondActivityTaskCompletedById(cctx, &workflowservice.RespondActivityTaskCompletedByIdRequest{
Copy link
Member

@cretz cretz Feb 12, 2024

Choose a reason for hiding this comment

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

While this is the approach of the old CLI, cl.CompleteActivityByID would have worked here too (you'd wrap the payload in rawValue). Arguably it'd be cleaner/clearer to use the high-level SDK client, but don't need to change now, but we might consider using the high-level API in the future.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK I'm happy to make that change and it would be easy, however, it looks like it doesn't support identity so I'm going to leave it for now.

Copy link
Member

@cretz cretz Feb 13, 2024

Choose a reason for hiding this comment

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

Usually smart clients set identity at the client level not the request level. That's what makes the --identity here so strange.

Comment on lines 45 to 49
metadata := map[string][]byte{"encoding": []byte("json/plain")}
var detailPayloads *common.Payloads
detailPayloads = nil
if len(c.Detail) > 0 {
detailPayloads, err = CreatePayloads([][]byte{[]byte(c.Detail)}, metadata, false)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
metadata := map[string][]byte{"encoding": []byte("json/plain")}
var detailPayloads *common.Payloads
detailPayloads = nil
if len(c.Detail) > 0 {
detailPayloads, err = CreatePayloads([][]byte{[]byte(c.Detail)}, metadata, false)
var detailPayloads *common.Payloads
if len(c.Detail) > 0 {
metadata := map[string][]byte{"encoding": []byte("json/plain")}
detailPayloads, err = CreatePayloads([][]byte{[]byte(c.Detail)}, metadata, false)

Little cleanup

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks!

@dandavison dandavison merged commit 678bd0b into temporalio:cli-rewrite Feb 12, 2024
5 checks passed
@dandavison
Copy link
Contributor Author

Thanks @cretz! Merged to keep the velocity up but there are some threads there we can follow-up in future PRs.

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.

2 participants