From 59981ba7b6fc7d8369bd7c48908da009ad9051a0 Mon Sep 17 00:00:00 2001 From: Yuri Date: Fri, 31 Jan 2025 11:51:04 -0800 Subject: [PATCH 1/4] Updates to the activity API --- go.mod | 8 +- go.sum | 16 ++-- temporalcli/commands.activity.go | 110 ++++++++++++++------------ temporalcli/commands.activity_test.go | 44 +++++++++-- temporalcli/commands.gen.go | 50 ++++++------ temporalcli/commandsgen/commands.yml | 80 ++++++++++++------- 6 files changed, 184 insertions(+), 124 deletions(-) diff --git a/go.mod b/go.mod index 33ed68d16..25d88daa7 100644 --- a/go.mod +++ b/go.mod @@ -9,15 +9,15 @@ require ( github.com/fatih/color v1.17.0 github.com/google/uuid v1.6.0 github.com/mattn/go-isatty v0.0.20 - github.com/nexus-rpc/sdk-go v0.1.0 + github.com/nexus-rpc/sdk-go v0.1.1 github.com/olekukonko/tablewriter v0.0.5 github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.10.0 github.com/temporalio/ui-server/v2 v2.32.0 - go.temporal.io/api v1.43.0 + go.temporal.io/api v1.43.3-0.20250130180025-c83bb3e83097 go.temporal.io/sdk v1.31.0 - go.temporal.io/server v1.26.2 + go.temporal.io/server v1.27.0-127.0.0.20250131044850-9fe70b4bdc01 google.golang.org/grpc v1.67.1 google.golang.org/protobuf v1.35.1 gopkg.in/yaml.v3 v3.0.1 @@ -102,7 +102,7 @@ require ( github.com/sirupsen/logrus v1.9.3 // indirect github.com/sony/gobreaker v1.0.0 // indirect github.com/stretchr/objx v0.5.2 // indirect - github.com/temporalio/ringpop-go v0.0.0-20241119001152-e505ebd8f887 // indirect + github.com/temporalio/ringpop-go v0.0.0-20250130211428-b97329e994f7 // indirect github.com/temporalio/sqlparser v0.0.0-20231115171017-f4060bcfa6cb // indirect github.com/temporalio/tchannel-go v1.22.1-0.20240528171429-1db37fdea938 // indirect github.com/twmb/murmur3 v1.1.8 // indirect diff --git a/go.sum b/go.sum index e915a2a47..a519e4130 100644 --- a/go.sum +++ b/go.sum @@ -230,8 +230,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= -github.com/nexus-rpc/sdk-go v0.1.0 h1:PUL/0vEY1//WnqyEHT5ao4LBRQ6MeNUihmnNGn0xMWY= -github.com/nexus-rpc/sdk-go v0.1.0/go.mod h1:TpfkM2Cw0Rlk9drGkoiSMpFqflKTiQLWUNyKJjF8mKQ= +github.com/nexus-rpc/sdk-go v0.1.1 h1:S63hhn4CpmwyoCUn8nVLfuKV+6sA/7hR57ohIQajDP0= +github.com/nexus-rpc/sdk-go v0.1.1/go.mod h1:TpfkM2Cw0Rlk9drGkoiSMpFqflKTiQLWUNyKJjF8mKQ= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= @@ -302,8 +302,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/temporalio/ringpop-go v0.0.0-20241119001152-e505ebd8f887 h1:08Y1jDl4UKVu+TiQHIVKcW6TKQaHl15vBKkcZ094/SA= -github.com/temporalio/ringpop-go v0.0.0-20241119001152-e505ebd8f887/go.mod h1:RE+CHmY+kOZQk47AQaVzwrGmxpflnLgTd6EOK0853j4= +github.com/temporalio/ringpop-go v0.0.0-20250130211428-b97329e994f7 h1:lEebX/hZss+TSH3EBwhztnBavJVj7pWGJOH8UgKHS0w= +github.com/temporalio/ringpop-go v0.0.0-20250130211428-b97329e994f7/go.mod h1:RE+CHmY+kOZQk47AQaVzwrGmxpflnLgTd6EOK0853j4= github.com/temporalio/sqlparser v0.0.0-20231115171017-f4060bcfa6cb h1:YzHH/U/dN7vMP+glybzcXRTczTrgfdRisNTzAj7La04= github.com/temporalio/sqlparser v0.0.0-20231115171017-f4060bcfa6cb/go.mod h1:143qKdh3G45IgV9p+gbAwp3ikRDI8mxsijFiXDfuxsw= github.com/temporalio/tchannel-go v1.22.1-0.20220818200552-1be8d8cffa5b/go.mod h1:c+V9Z/ZgkzAdyGvHrvC5AsXgN+M9Qwey04cBdKYzV7U= @@ -357,12 +357,12 @@ go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HY go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= -go.temporal.io/api v1.43.0 h1:lBhq+u5qFJqGMXwWsmg/i8qn1UA/3LCwVc88l2xUMHg= -go.temporal.io/api v1.43.0/go.mod h1:1WwYUMo6lao8yl0371xWUm13paHExN5ATYT/B7QtFis= +go.temporal.io/api v1.43.3-0.20250130180025-c83bb3e83097 h1:C5X7/ScMCL8g64b/h2KY5BS7xua6AdKmIU+gUqzemkU= +go.temporal.io/api v1.43.3-0.20250130180025-c83bb3e83097/go.mod h1:1WwYUMo6lao8yl0371xWUm13paHExN5ATYT/B7QtFis= go.temporal.io/sdk v1.31.0 h1:CLYiP0R5Sdj0gq8LyYKDDz4ccGOdJPR8wNGJU0JGwj8= go.temporal.io/sdk v1.31.0/go.mod h1:8U8H7rF9u4Hyb4Ry9yiEls5716DHPNvVITPNkgWUwE8= -go.temporal.io/server v1.26.2 h1:vDW11lxslYPlGDbQklWi/tqbkVZ2ExtRO1jNjvZmUUI= -go.temporal.io/server v1.26.2/go.mod h1:tgY+4z/PuIdqs6ouV1bT90RWSWfEioWkzmrNrLYLUrk= +go.temporal.io/server v1.27.0-127.0.0.20250131044850-9fe70b4bdc01 h1:Taf5yj5gSUV5hPDVuVYFi4z6REUmIvK9A1dwOI0h3IM= +go.temporal.io/server v1.27.0-127.0.0.20250131044850-9fe70b4bdc01/go.mod h1:h6wn6UEKORDV84T0sbNzWjG4Jq9fMpxIlERrVjYIYCI= go.temporal.io/version v0.3.0 h1:dMrei9l9NyHt8nG6EB8vAwDLLTwx2SvRyucCSumAiig= go.temporal.io/version v0.3.0/go.mod h1:UA9S8/1LaKYae6TyD9NaPMJTZb911JcbqghI2CBSP78= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= diff --git a/temporalcli/commands.activity.go b/temporalcli/commands.activity.go index c0953f883..442a0a5b3 100644 --- a/temporalcli/commands.activity.go +++ b/temporalcli/commands.activity.go @@ -4,7 +4,6 @@ import ( "fmt" "time" - "github.com/google/uuid" "github.com/temporalio/cli/temporalcli/internal/printer" activitypb "go.temporal.io/api/activity/v1" "go.temporal.io/api/common/v1" @@ -156,18 +155,18 @@ func (c *TemporalActivityUpdateOptionsCommand) run(cctx *CommandContext, args [] updatePath = append(updatePath, "retry_policy.maximum_attempts") } - result, err := cl.WorkflowService().UpdateActivityOptionsById(cctx, &workflowservice.UpdateActivityOptionsByIdRequest{ - Namespace: c.Parent.Namespace, - WorkflowId: c.WorkflowId, - RunId: c.RunId, - ActivityId: c.ActivityId, + result, err := cl.WorkflowService().UpdateActivityOptions(cctx, &workflowservice.UpdateActivityOptionsRequest{ + Namespace: c.Parent.Namespace, + Execution: &common.WorkflowExecution{ + WorkflowId: c.WorkflowId, + RunId: c.RunId, + }, + Activity: &workflowservice.UpdateActivityOptionsRequest_Id{Id: c.ActivityId}, ActivityOptions: activityOptions, UpdateMask: &fieldmaskpb.FieldMask{ Paths: updatePath, }, - - Identity: c.Identity, - RequestId: uuid.NewString(), + Identity: c.Identity, }) if err != nil { return fmt.Errorf("unable to update Activity options: %w", err) @@ -199,16 +198,26 @@ func (c *TemporalActivityPauseCommand) run(cctx *CommandContext, args []string) } defer cl.Close() - _, err = cl.WorkflowService().PauseActivityById(cctx, &workflowservice.PauseActivityByIdRequest{ - Namespace: c.Parent.Namespace, - WorkflowId: c.WorkflowId, - RunId: c.RunId, - ActivityId: c.ActivityId, - Identity: c.Identity, - RequestId: uuid.NewString(), - }) + request := &workflowservice.PauseActivityRequest{ + Namespace: c.Parent.Namespace, + Execution: &common.WorkflowExecution{ + WorkflowId: c.WorkflowId, + RunId: c.RunId, + }, + Identity: c.Identity, + } + + if c.ActivityType != "" { + request.Activity = &workflowservice.PauseActivityRequest_Type{Type: c.ActivityType} + } else if c.ActivityId != "" { + request.Activity = &workflowservice.PauseActivityRequest_Id{Id: c.ActivityId} + } else { + return fmt.Errorf("either Activity Type or Activity Id must be provided") + } + + _, err = cl.WorkflowService().PauseActivity(cctx, request) if err != nil { - return fmt.Errorf("unable to update Activity options: %w", err) + return fmt.Errorf("unable to pause Activity: %w", err) } return nil @@ -221,32 +230,26 @@ func (c *TemporalActivityUnpauseCommand) run(cctx *CommandContext, args []string } defer cl.Close() - request := &workflowservice.UnpauseActivityByIdRequest{ - Namespace: c.Parent.Namespace, - WorkflowId: c.WorkflowId, - RunId: c.RunId, - ActivityId: c.ActivityId, - Identity: c.Identity, + request := &workflowservice.UnpauseActivityRequest{ + Namespace: c.Parent.Namespace, + Execution: &common.WorkflowExecution{ + WorkflowId: c.WorkflowId, + RunId: c.RunId, + }, + ResetAttempts: c.ResetAttempts, + ResetHeartbeat: c.ResetHeartbeats, + Identity: c.Identity, } - if c.Reset { - request.Operation = &workflowservice.UnpauseActivityByIdRequest_Reset_{ - Reset_: &workflowservice.UnpauseActivityByIdRequest_ResetOperation{ - NoWait: c.NoWait, - ResetHeartbeat: c.ResetHeartbeats, - }, - } + + if c.ActivityType != "" { + request.Activity = &workflowservice.UnpauseActivityRequest_Type{Type: c.ActivityType} + } else if c.ActivityId != "" { + request.Activity = &workflowservice.UnpauseActivityRequest_Id{Id: c.ActivityId} } else { - if c.ResetHeartbeats { - return fmt.Errorf("reset-heartbeats flag can only be used with reset flag") - } - request.Operation = &workflowservice.UnpauseActivityByIdRequest_Resume{ - Resume: &workflowservice.UnpauseActivityByIdRequest_ResumeOperation{ - NoWait: c.NoWait, - }, - } + return fmt.Errorf("either Activity Type or Activity Id must be provided") } - _, err = cl.WorkflowService().UnpauseActivityById(cctx, request) + _, err = cl.WorkflowService().UnpauseActivity(cctx, request) if err != nil { return fmt.Errorf("unable to uppause an Activity: %w", err) } @@ -261,28 +264,37 @@ func (c *TemporalActivityResetCommand) run(cctx *CommandContext, args []string) } defer cl.Close() - request := &workflowservice.ResetActivityByIdRequest{ - Namespace: c.Parent.Namespace, - WorkflowId: c.WorkflowId, - RunId: c.RunId, - ActivityId: c.ActivityId, + request := &workflowservice.ResetActivityRequest{ + Namespace: c.Parent.Namespace, + Execution: &common.WorkflowExecution{ + WorkflowId: c.WorkflowId, + RunId: c.RunId, + }, Identity: c.Identity, - NoWait: c.NoWait, + KeepPaused: c.KeepPaused, ResetHeartbeat: c.ResetHeartbeats, } - resp, err := cl.WorkflowService().ResetActivityById(cctx, request) + if c.ActivityType != "" { + request.Activity = &workflowservice.ResetActivityRequest_Type{Type: c.ActivityType} + } else if c.ActivityId != "" { + request.Activity = &workflowservice.ResetActivityRequest_Id{Id: c.ActivityId} + } else { + return fmt.Errorf("either Activity Type or Activity Id must be provided") + } + + resp, err := cl.WorkflowService().ResetActivity(cctx, request) if err != nil { return fmt.Errorf("unable to reset an Activity: %w", err) } resetResponse := struct { - NoWait bool `json:"noWait"` + KeepPaused bool `json:"keepPaused"` ResetHeartbeats bool `json:"resetHeartbeats"` ServerResponse bool `json:"-"` }{ ServerResponse: resp != nil, - NoWait: c.NoWait, + KeepPaused: c.KeepPaused, ResetHeartbeats: c.ResetHeartbeats, } diff --git a/temporalcli/commands.activity_test.go b/temporalcli/commands.activity_test.go index fc2f3e4ea..db11b0dd8 100644 --- a/temporalcli/commands.activity_test.go +++ b/temporalcli/commands.activity_test.go @@ -206,30 +206,59 @@ func (s *SharedServerSuite) TestActivityPauseUnpause() { "--run-id", run.GetRunID(), "--identity", identity, "--address", s.Address(), - "--reset", + "--reset-attempts", ) s.NoError(res.Err) } -func (s *SharedServerSuite) TestActivityUnPause_Failed() { +func (s *SharedServerSuite) TestActivityPauseUnpauseByType() { run := s.waitActivityStarted() wid := run.GetID() - aid := "dev-activity-id" + at := "DevActivity" identity := "MyIdentity" - // should fail because --reset-heartbeat is provided, but --reset flag is missing res := s.Execute( + "activity", "pause", + "--activity-type", at, + "--workflow-id", wid, + "--run-id", run.GetRunID(), + "--identity", identity, + "--address", s.Address(), + ) + + s.NoError(res.Err) + + res = s.Execute( "activity", "unpause", - "--activity-id", aid, + "--activity-type", at, "--workflow-id", wid, "--run-id", run.GetRunID(), "--identity", identity, "--address", s.Address(), - "--reset-heartbeats", + "--reset-attempts", ) - s.Error(res.Err) + s.NoError(res.Err) +} + +func (s *SharedServerSuite) TestActivityCommandFailed_NoActivityTpeOrid() { + run := s.waitActivityStarted() + wid := run.GetID() + identity := "MyIdentity" + + commands := []string{"pause", "unpause", "reset"} + for _, command := range commands { + // should fail because both activity-id and activity-type are not provided + res := s.Execute( + "activity", command, + "--workflow-id", wid, + "--run-id", run.GetRunID(), + "--identity", identity, + "--address", s.Address(), + ) + s.Error(res.Err) + } } func (s *SharedServerSuite) TestActivityReset() { @@ -253,7 +282,6 @@ func (s *SharedServerSuite) TestActivityReset() { s.ContainsOnSameLine(out, "ServerResponse", "true") // reset should fail because activity is not found - res = s.Execute( "activity", "reset", "--activity-id", "fake_id", diff --git a/temporalcli/commands.gen.go b/temporalcli/commands.gen.go index 3ddc1c1ec..b5475a3b1 100644 --- a/temporalcli/commands.gen.go +++ b/temporalcli/commands.gen.go @@ -3,15 +3,14 @@ package temporalcli import ( + "os" + "time" + "github.com/mattn/go-isatty" "github.com/spf13/cobra" "github.com/spf13/pflag" - - "os" - - "time" ) var hasHighlighting = isatty.IsTerminal(os.Stdout.Fd()) @@ -419,8 +418,9 @@ type TemporalActivityPauseCommand struct { Parent *TemporalActivityCommand Command cobra.Command WorkflowReferenceOptions - ActivityId string - Identity string + ActivityId string + ActivityType string + Identity string } func NewTemporalActivityPauseCommand(cctx *CommandContext, parent *TemporalActivityCommand) *TemporalActivityPauseCommand { @@ -430,13 +430,13 @@ func NewTemporalActivityPauseCommand(cctx *CommandContext, parent *TemporalActiv s.Command.Use = "pause [flags]" s.Command.Short = "Pause an Activity" if hasHighlighting { - s.Command.Long = "Pause an Activity.\n\nIf the Activity is not currently running (e.g. because it previously\nfailed), it will not be run again until it is unpaused.\n\nHowever, if the Activity is currently running, it will run to completion.\nIf the Activity is on its last retry attempt and fails, the failure will\nbe returned to the caller, just as if the Activity had not been paused.\n\nSpecify the Activity and Workflow IDs:\n\n\x1b[1mtemporal activity pause \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId\x1b[0m" + s.Command.Long = "Pause an Activity.\n\nIf the Activity is not currently running (e.g. because it previously\nfailed), it will not be run again until it is unpaused.\n\nHowever, if the Activity is currently running, it will run to completion.\nIf the Activity is on its last retry attempt and fails, the failure will\nbe returned to the caller, just as if the Activity had not been paused.\n\nActivities can be specified by their Activity ID or Activity Type. \nOne of those parameters must be provided. If both are provided - Activity\nType will be used, and Activity ID will be ignored.\n\n\x1b[1mSpecify the Activity and Workflow IDs:\x1b[0m\ntemporal activity pause \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId\n```" } else { - s.Command.Long = "Pause an Activity.\n\nIf the Activity is not currently running (e.g. because it previously\nfailed), it will not be run again until it is unpaused.\n\nHowever, if the Activity is currently running, it will run to completion.\nIf the Activity is on its last retry attempt and fails, the failure will\nbe returned to the caller, just as if the Activity had not been paused.\n\nSpecify the Activity and Workflow IDs:\n\n```\ntemporal activity pause \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId\n```" + s.Command.Long = "Pause an Activity.\n\nIf the Activity is not currently running (e.g. because it previously\nfailed), it will not be run again until it is unpaused.\n\nHowever, if the Activity is currently running, it will run to completion.\nIf the Activity is on its last retry attempt and fails, the failure will\nbe returned to the caller, just as if the Activity had not been paused.\n\nActivities can be specified by their Activity ID or Activity Type. \nOne of those parameters must be provided. If both are provided - Activity\nType will be used, and Activity ID will be ignored.\n\n```\n\nSpecify the Activity and Workflow IDs:\n\n```\ntemporal activity pause \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId\n```" } s.Command.Args = cobra.NoArgs - s.Command.Flags().StringVarP(&s.ActivityId, "activity-id", "a", "", "Activity ID to pause. Required.") - _ = cobra.MarkFlagRequired(s.Command.Flags(), "activity-id") + s.Command.Flags().StringVarP(&s.ActivityId, "activity-id", "a", "", "Activity ID to pause.") + s.Command.Flags().StringVarP(&s.ActivityType, "activity-type", "t", "", "Activity Type to pause.") s.Command.Flags().StringVar(&s.Identity, "identity", "", "Identity of the user submitting this request.") s.WorkflowReferenceOptions.buildFlags(cctx, s.Command.Flags()) s.Command.Run = func(c *cobra.Command, args []string) { @@ -452,8 +452,9 @@ type TemporalActivityResetCommand struct { Command cobra.Command WorkflowReferenceOptions ActivityId string + ActivityType string Identity string - NoWait bool + KeepPaused bool ResetHeartbeats bool } @@ -464,15 +465,15 @@ func NewTemporalActivityResetCommand(cctx *CommandContext, parent *TemporalActiv s.Command.Use = "reset [flags]" s.Command.Short = "Reset an Activity" if hasHighlighting { - s.Command.Long = "Resetting an activity resets both the number of attempts and the activity \ntimeout. If activity is paused, it will be un-paused. \n\nIf the \x1b[1mno-wait\x1b[0m flag is provided, the activity will be rescheduled \nimmediately. Even if the activity is currently running.\nIf the \x1b[1mno-wait\x1b[0m flag is not provided, the activity will be scheduled \nafter the current instance completes, if needed. \nIf the 'reset_heartbeats' flag is set, the activity heartbeat timer and \nheartbeats will be reset.\n\nSpecify the Activity and Workflow IDs:\n\n\x1b[1mtemporal activity reset \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId\n --no-wait\n --reset-heartbeats\x1b[0m" + s.Command.Long = "Resetting an activity resets both the number of attempts and the activity \ntimeout. \n\nIf activity is paused and 'keep_paused' flag is not provided - it will be \nunpaused.\nIf activity is paused and 'keep_paused' flag is provided - it will stay \npaused.\nIf activity is waiting for the retry, is will be rescheduled immediately.\nIf the 'reset_heartbeats' flag is set, the activity heartbeat timer and \nheartbeats will be reset.\n\nActivities can be specified by their Activity ID or Activity Type. \nOne of those parameters must be provided. If both are provided - Activity\nType will be used, and Activity ID will be ignored. \n\nSpecify the Activity Type of ID and Workflow IDs:\n\n\x1b[1mtemporal activity reset \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId\n --keep-paused\n --reset-heartbeats\x1b[0m" } else { - s.Command.Long = "Resetting an activity resets both the number of attempts and the activity \ntimeout. If activity is paused, it will be un-paused. \n\nIf the `no-wait` flag is provided, the activity will be rescheduled \nimmediately. Even if the activity is currently running.\nIf the `no-wait` flag is not provided, the activity will be scheduled \nafter the current instance completes, if needed. \nIf the 'reset_heartbeats' flag is set, the activity heartbeat timer and \nheartbeats will be reset.\n\nSpecify the Activity and Workflow IDs:\n\n```\ntemporal activity reset \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId\n --no-wait\n --reset-heartbeats\n```" + s.Command.Long = "Resetting an activity resets both the number of attempts and the activity \ntimeout. \n\nIf activity is paused and 'keep_paused' flag is not provided - it will be \nunpaused.\nIf activity is paused and 'keep_paused' flag is provided - it will stay \npaused.\nIf activity is waiting for the retry, is will be rescheduled immediately.\nIf the 'reset_heartbeats' flag is set, the activity heartbeat timer and \nheartbeats will be reset.\n\nActivities can be specified by their Activity ID or Activity Type. \nOne of those parameters must be provided. If both are provided - Activity\nType will be used, and Activity ID will be ignored. \n\nSpecify the Activity Type of ID and Workflow IDs:\n\n```\ntemporal activity reset \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId\n --keep-paused\n --reset-heartbeats\n```" } s.Command.Args = cobra.NoArgs - s.Command.Flags().StringVarP(&s.ActivityId, "activity-id", "a", "", "Activity ID to pause. Required.") - _ = cobra.MarkFlagRequired(s.Command.Flags(), "activity-id") + s.Command.Flags().StringVarP(&s.ActivityId, "activity-id", "a", "", "Activity ID to pause.") + s.Command.Flags().StringVarP(&s.ActivityType, "activity-type", "t", "", "Activity Type to pause.") s.Command.Flags().StringVar(&s.Identity, "identity", "", "Identity of the user submitting this request.") - s.Command.Flags().BoolVar(&s.NoWait, "no-wait", false, "Schedule the Activity immediately, even if its retry timeout has not expired or the activity is currently running.") + s.Command.Flags().BoolVar(&s.KeepPaused, "keep-paused", false, "If activity was paused - it will stay paused.") s.Command.Flags().BoolVar(&s.ResetHeartbeats, "reset-heartbeats", false, "Reset the Activity's heartbeat.") s.WorkflowReferenceOptions.buildFlags(cctx, s.Command.Flags()) s.Command.Run = func(c *cobra.Command, args []string) { @@ -488,9 +489,9 @@ type TemporalActivityUnpauseCommand struct { Command cobra.Command WorkflowReferenceOptions ActivityId string + ActivityType string Identity string - Reset bool - NoWait bool + ResetAttempts bool ResetHeartbeats bool } @@ -501,17 +502,16 @@ func NewTemporalActivityUnpauseCommand(cctx *CommandContext, parent *TemporalAct s.Command.Use = "unpause [flags]" s.Command.Short = "Unpause an Activity" if hasHighlighting { - s.Command.Long = "Re-schedule a previously-paused Activity for execution.\n\nIf the Activity is not running and is past its retry timeout, it will be\nscheduled immediately. Otherwise, it will be scheduled after its retry\ntimeout expires. The Activity can be retried immediately with \x1b[1m--no-wait\x1b[0m.\n\nUse \x1b[1m--reset\x1b[0m to reset the number of previous run attempts to zero. For\nexample, if an Activity is near the maximum number of attempts N specified\nin its retry policy, \x1b[1m--reset\x1b[0m will allow the Activity to be retried\nanother N times after unpausing.\n\nSpecify the Activity and Workflow IDs:\n\n\x1b[1mtemporal activity unpause \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId\n --reset\n --no-wait\n --reset-heartbeats\x1b[0m" + s.Command.Long = "Re-schedule a previously-paused Activity for execution.\n\nIf the Activity is not running and is past its retry timeout, it will be\nscheduled immediately. Otherwise, it will be scheduled after its retry\ntimeout expires. \n\nUse \x1b[1m--reset-attempts\x1b[0m to reset the number of previous run attempts to \nzero. For example, if an Activity is near the maximum number of attempts \nN specified in its retry policy, \x1b[1m--reset-attempts\x1b[0m will allow the \nActivity to be retried another N times after unpausing.\n\nUse \x1b[1m--reset-heartbeat\x1b[0m to reset the Activity's heartbeats. \n\nActivities can be specified by their Activity ID or Activity Type. \nOne of those parameters must be provided. If both are provided - Activity\nType will be used, and Activity ID will be ignored. \n\nSpecify the Activity ID or Type and Workflow IDs:\n\n\x1b[1mtemporal activity unpause \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId\n --reset-attempts\n --reset-heartbeats\x1b[0m" } else { - s.Command.Long = "Re-schedule a previously-paused Activity for execution.\n\nIf the Activity is not running and is past its retry timeout, it will be\nscheduled immediately. Otherwise, it will be scheduled after its retry\ntimeout expires. The Activity can be retried immediately with `--no-wait`.\n\nUse `--reset` to reset the number of previous run attempts to zero. For\nexample, if an Activity is near the maximum number of attempts N specified\nin its retry policy, `--reset` will allow the Activity to be retried\nanother N times after unpausing.\n\nSpecify the Activity and Workflow IDs:\n\n```\ntemporal activity unpause \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId\n --reset\n --no-wait\n --reset-heartbeats\n```" + s.Command.Long = "Re-schedule a previously-paused Activity for execution.\n\nIf the Activity is not running and is past its retry timeout, it will be\nscheduled immediately. Otherwise, it will be scheduled after its retry\ntimeout expires. \n\nUse `--reset-attempts` to reset the number of previous run attempts to \nzero. For example, if an Activity is near the maximum number of attempts \nN specified in its retry policy, `--reset-attempts` will allow the \nActivity to be retried another N times after unpausing.\n\nUse `--reset-heartbeat` to reset the Activity's heartbeats. \n\nActivities can be specified by their Activity ID or Activity Type. \nOne of those parameters must be provided. If both are provided - Activity\nType will be used, and Activity ID will be ignored. \n\nSpecify the Activity ID or Type and Workflow IDs:\n\n```\ntemporal activity unpause \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId\n --reset-attempts\n --reset-heartbeats\n```" } s.Command.Args = cobra.NoArgs - s.Command.Flags().StringVarP(&s.ActivityId, "activity-id", "a", "", "Activity ID to pause. Required.") - _ = cobra.MarkFlagRequired(s.Command.Flags(), "activity-id") + s.Command.Flags().StringVarP(&s.ActivityId, "activity-id", "a", "", "Activity ID to unpause.") + s.Command.Flags().StringVarP(&s.ActivityType, "activity-type", "t", "", "Activity Type to unpause.") s.Command.Flags().StringVar(&s.Identity, "identity", "", "Identity of the user submitting this request.") - s.Command.Flags().BoolVar(&s.Reset, "reset", false, "Also reset the activity.") - s.Command.Flags().BoolVar(&s.NoWait, "no-wait", false, "Schedule the Activity immediately, even if its retry timeout has not expired.") - s.Command.Flags().BoolVar(&s.ResetHeartbeats, "reset-heartbeats", false, "Reset the Activity's heartbeat timeout. Only works with --reset.") + s.Command.Flags().BoolVar(&s.ResetAttempts, "reset-attempts", false, "Also reset the activity attempts.") + s.Command.Flags().BoolVar(&s.ResetHeartbeats, "reset-heartbeats", false, "Reset the Activity's heartbeats. Only works with --reset-attempts.") s.WorkflowReferenceOptions.buildFlags(cctx, s.Command.Flags()) s.Command.Run = func(c *cobra.Command, args []string) { if err := s.run(cctx, args); err != nil { diff --git a/temporalcli/commandsgen/commands.yml b/temporalcli/commandsgen/commands.yml index f6832f103..ff720fa81 100644 --- a/temporalcli/commandsgen/commands.yml +++ b/temporalcli/commandsgen/commands.yml @@ -390,6 +390,12 @@ commands: However, if the Activity is currently running, it will run to completion. If the Activity is on its last retry attempt and fails, the failure will be returned to the caller, just as if the Activity had not been paused. + + Activities can be specified by their Activity ID or Activity Type. + One of those parameters must be provided. If both are provided - Activity + Type will be used, and Activity ID will be ignored. + + ``` Specify the Activity and Workflow IDs: @@ -403,7 +409,10 @@ commands: short: a type: string description: Activity ID to pause. - required: true + - name: activity-type + short: a + type: string + description: Activity Type to pause. - name: identity type: string description: Identity of the user submitting this request. @@ -417,42 +426,47 @@ commands: If the Activity is not running and is past its retry timeout, it will be scheduled immediately. Otherwise, it will be scheduled after its retry - timeout expires. The Activity can be retried immediately with `--no-wait`. + timeout expires. - Use `--reset` to reset the number of previous run attempts to zero. For - example, if an Activity is near the maximum number of attempts N specified - in its retry policy, `--reset` will allow the Activity to be retried - another N times after unpausing. + Use `--reset-attempts` to reset the number of previous run attempts to + zero. For example, if an Activity is near the maximum number of attempts + N specified in its retry policy, `--reset-attempts` will allow the + Activity to be retried another N times after unpausing. + + Use `--reset-heartbeat` to reset the Activity's heartbeats. + + Activities can be specified by their Activity ID or Activity Type. + One of those parameters must be provided. If both are provided - Activity + Type will be used, and Activity ID will be ignored. - Specify the Activity and Workflow IDs: + Specify the Activity ID or Type and Workflow IDs: ``` temporal activity unpause \ --activity-id YourActivityId \ --workflow-id YourWorkflowId - --reset - --no-wait + --reset-attempts --reset-heartbeats ``` options: - name: activity-id short: a type: string - description: Activity ID to pause. - required: true + description: Activity ID to unpause. + - name: activity-type + short: a + type: string + description: Activity Type to unpause. - name: identity type: string description: Identity of the user submitting this request. - - name: reset + - name: reset-attempts type: bool - description: Also reset the activity. - - name: no-wait - type: bool - description: | - Schedule the Activity immediately, even if its retry timeout has not expired. + description: Also reset the activity attempts. - name: reset-heartbeats type: bool - description: Reset the Activity's heartbeat timeout. Only works with --reset. + description: | + Reset the Activity's heartbeats. Only works with --reset-attempts. option-sets: - workflow reference @@ -460,22 +474,27 @@ commands: summary: Reset an Activity description: | Resetting an activity resets both the number of attempts and the activity - timeout. If activity is paused, it will be un-paused. + timeout. - If the `no-wait` flag is provided, the activity will be rescheduled - immediately. Even if the activity is currently running. - If the `no-wait` flag is not provided, the activity will be scheduled - after the current instance completes, if needed. + If activity is paused and 'keep_paused' flag is not provided - it will be + unpaused. + If activity is paused and 'keep_paused' flag is provided - it will stay + paused. + If activity is waiting for the retry, is will be rescheduled immediately. If the 'reset_heartbeats' flag is set, the activity heartbeat timer and heartbeats will be reset. - Specify the Activity and Workflow IDs: + Activities can be specified by their Activity ID or Activity Type. + One of those parameters must be provided. If both are provided - Activity + Type will be used, and Activity ID will be ignored. + + Specify the Activity Type of ID and Workflow IDs: ``` temporal activity reset \ --activity-id YourActivityId \ --workflow-id YourWorkflowId - --no-wait + --keep-paused --reset-heartbeats ``` options: @@ -483,15 +502,16 @@ commands: short: a type: string description: Activity ID to pause. - required: true + - name: activity-type + short: a + type: string + description: Activity Type to pause. - name: identity type: string description: Identity of the user submitting this request. - - name: no-wait + - name: keep-paused type: bool - description: | - Schedule the Activity immediately, even if its retry timeout has not - expired or the activity is currently running. + description: If activity was paused - it will stay paused. - name: reset-heartbeats type: bool description: Reset the Activity's heartbeat. From f4aed6a96c557c61da6eb17f20d2bcbbf32f81b2 Mon Sep 17 00:00:00 2001 From: Yuri Date: Fri, 31 Jan 2025 13:07:34 -0800 Subject: [PATCH 2/4] run gen-commands --- temporalcli/commands.gen.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/temporalcli/commands.gen.go b/temporalcli/commands.gen.go index b5475a3b1..26f588b78 100644 --- a/temporalcli/commands.gen.go +++ b/temporalcli/commands.gen.go @@ -3,14 +3,15 @@ package temporalcli import ( - "os" - "time" - "github.com/mattn/go-isatty" "github.com/spf13/cobra" "github.com/spf13/pflag" + + "os" + + "time" ) var hasHighlighting = isatty.IsTerminal(os.Stdout.Fd()) @@ -436,7 +437,7 @@ func NewTemporalActivityPauseCommand(cctx *CommandContext, parent *TemporalActiv } s.Command.Args = cobra.NoArgs s.Command.Flags().StringVarP(&s.ActivityId, "activity-id", "a", "", "Activity ID to pause.") - s.Command.Flags().StringVarP(&s.ActivityType, "activity-type", "t", "", "Activity Type to pause.") + s.Command.Flags().StringVarP(&s.ActivityType, "activity-type", "a", "", "Activity Type to pause.") s.Command.Flags().StringVar(&s.Identity, "identity", "", "Identity of the user submitting this request.") s.WorkflowReferenceOptions.buildFlags(cctx, s.Command.Flags()) s.Command.Run = func(c *cobra.Command, args []string) { @@ -471,7 +472,7 @@ func NewTemporalActivityResetCommand(cctx *CommandContext, parent *TemporalActiv } s.Command.Args = cobra.NoArgs s.Command.Flags().StringVarP(&s.ActivityId, "activity-id", "a", "", "Activity ID to pause.") - s.Command.Flags().StringVarP(&s.ActivityType, "activity-type", "t", "", "Activity Type to pause.") + s.Command.Flags().StringVarP(&s.ActivityType, "activity-type", "a", "", "Activity Type to pause.") s.Command.Flags().StringVar(&s.Identity, "identity", "", "Identity of the user submitting this request.") s.Command.Flags().BoolVar(&s.KeepPaused, "keep-paused", false, "If activity was paused - it will stay paused.") s.Command.Flags().BoolVar(&s.ResetHeartbeats, "reset-heartbeats", false, "Reset the Activity's heartbeat.") @@ -508,7 +509,7 @@ func NewTemporalActivityUnpauseCommand(cctx *CommandContext, parent *TemporalAct } s.Command.Args = cobra.NoArgs s.Command.Flags().StringVarP(&s.ActivityId, "activity-id", "a", "", "Activity ID to unpause.") - s.Command.Flags().StringVarP(&s.ActivityType, "activity-type", "t", "", "Activity Type to unpause.") + s.Command.Flags().StringVarP(&s.ActivityType, "activity-type", "a", "", "Activity Type to unpause.") s.Command.Flags().StringVar(&s.Identity, "identity", "", "Identity of the user submitting this request.") s.Command.Flags().BoolVar(&s.ResetAttempts, "reset-attempts", false, "Also reset the activity attempts.") s.Command.Flags().BoolVar(&s.ResetHeartbeats, "reset-heartbeats", false, "Reset the Activity's heartbeats. Only works with --reset-attempts.") From 38362d54699366f9a3cbc7c1d639d72ae57f33c8 Mon Sep 17 00:00:00 2001 From: Yuri Date: Fri, 31 Jan 2025 13:21:14 -0800 Subject: [PATCH 3/4] fix shortcuts --- temporalcli/commands.gen.go | 6 +++--- temporalcli/commandsgen/commands.yml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/temporalcli/commands.gen.go b/temporalcli/commands.gen.go index 26f588b78..3800b5a19 100644 --- a/temporalcli/commands.gen.go +++ b/temporalcli/commands.gen.go @@ -437,7 +437,7 @@ func NewTemporalActivityPauseCommand(cctx *CommandContext, parent *TemporalActiv } s.Command.Args = cobra.NoArgs s.Command.Flags().StringVarP(&s.ActivityId, "activity-id", "a", "", "Activity ID to pause.") - s.Command.Flags().StringVarP(&s.ActivityType, "activity-type", "a", "", "Activity Type to pause.") + s.Command.Flags().StringVarP(&s.ActivityType, "activity-type", "g", "", "Activity Type to pause.") s.Command.Flags().StringVar(&s.Identity, "identity", "", "Identity of the user submitting this request.") s.WorkflowReferenceOptions.buildFlags(cctx, s.Command.Flags()) s.Command.Run = func(c *cobra.Command, args []string) { @@ -472,7 +472,7 @@ func NewTemporalActivityResetCommand(cctx *CommandContext, parent *TemporalActiv } s.Command.Args = cobra.NoArgs s.Command.Flags().StringVarP(&s.ActivityId, "activity-id", "a", "", "Activity ID to pause.") - s.Command.Flags().StringVarP(&s.ActivityType, "activity-type", "a", "", "Activity Type to pause.") + s.Command.Flags().StringVarP(&s.ActivityType, "activity-type", "g", "", "Activity Type to pause.") s.Command.Flags().StringVar(&s.Identity, "identity", "", "Identity of the user submitting this request.") s.Command.Flags().BoolVar(&s.KeepPaused, "keep-paused", false, "If activity was paused - it will stay paused.") s.Command.Flags().BoolVar(&s.ResetHeartbeats, "reset-heartbeats", false, "Reset the Activity's heartbeat.") @@ -509,7 +509,7 @@ func NewTemporalActivityUnpauseCommand(cctx *CommandContext, parent *TemporalAct } s.Command.Args = cobra.NoArgs s.Command.Flags().StringVarP(&s.ActivityId, "activity-id", "a", "", "Activity ID to unpause.") - s.Command.Flags().StringVarP(&s.ActivityType, "activity-type", "a", "", "Activity Type to unpause.") + s.Command.Flags().StringVarP(&s.ActivityType, "activity-type", "g", "", "Activity Type to unpause.") s.Command.Flags().StringVar(&s.Identity, "identity", "", "Identity of the user submitting this request.") s.Command.Flags().BoolVar(&s.ResetAttempts, "reset-attempts", false, "Also reset the activity attempts.") s.Command.Flags().BoolVar(&s.ResetHeartbeats, "reset-heartbeats", false, "Reset the Activity's heartbeats. Only works with --reset-attempts.") diff --git a/temporalcli/commandsgen/commands.yml b/temporalcli/commandsgen/commands.yml index ff720fa81..dadec7442 100644 --- a/temporalcli/commandsgen/commands.yml +++ b/temporalcli/commandsgen/commands.yml @@ -410,7 +410,7 @@ commands: type: string description: Activity ID to pause. - name: activity-type - short: a + short: g type: string description: Activity Type to pause. - name: identity @@ -454,7 +454,7 @@ commands: type: string description: Activity ID to unpause. - name: activity-type - short: a + short: g type: string description: Activity Type to unpause. - name: identity @@ -503,7 +503,7 @@ commands: type: string description: Activity ID to pause. - name: activity-type - short: a + short: g type: string description: Activity Type to pause. - name: identity From 8ae692b3cfb9aa5077fd489e16461245ed581f52 Mon Sep 17 00:00:00 2001 From: Yuri Date: Mon, 3 Feb 2025 09:24:06 -0800 Subject: [PATCH 4/4] just to trigger rebuild --- temporalcli/commands.activity_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/temporalcli/commands.activity_test.go b/temporalcli/commands.activity_test.go index db11b0dd8..7fbb85203 100644 --- a/temporalcli/commands.activity_test.go +++ b/temporalcli/commands.activity_test.go @@ -226,7 +226,6 @@ func (s *SharedServerSuite) TestActivityPauseUnpauseByType() { "--identity", identity, "--address", s.Address(), ) - s.NoError(res.Err) res = s.Execute(