Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 18 additions & 9 deletions temporalcli/commands.activity.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,12 +208,15 @@ func (c *TemporalActivityPauseCommand) run(cctx *CommandContext, args []string)
Identity: c.Identity,
}

if err := c.ActivityReferenceOptions.validateFlags(); err != nil {
return err
}

if c.ActivityType != "" {
request.Activity = &workflowservice.PauseActivityRequest_Type{Type: c.ActivityType}
} else if c.ActivityId != "" {
}
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)
Expand Down Expand Up @@ -261,12 +264,15 @@ func (c *TemporalActivityUnpauseCommand) run(cctx *CommandContext, args []string
Identity: c.Identity,
}

if err := c.ActivityReferenceOptions.validateFlags(); err != nil {
return err
}

if c.ActivityType != "" {
request.Activity = &workflowservice.UnpauseActivityRequest_Type{Type: c.ActivityType}
} else if c.ActivityId != "" {
}
if c.ActivityId != "" {
request.Activity = &workflowservice.UnpauseActivityRequest_Id{Id: c.ActivityId}
} else {
return fmt.Errorf("either Activity Type or Activity Id must be provided")
}

_, err = cl.WorkflowService().UnpauseActivity(cctx, request)
Expand Down Expand Up @@ -318,12 +324,15 @@ func (c *TemporalActivityResetCommand) run(cctx *CommandContext, args []string)
ResetHeartbeat: c.ResetHeartbeats,
}

if err := c.ActivityReferenceOptions.validateFlags(); err != nil {
return err
}

if c.ActivityType != "" {
request.Activity = &workflowservice.ResetActivityRequest_Type{Type: c.ActivityType}
} else if c.ActivityId != "" {
}
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)
Expand Down
10 changes: 10 additions & 0 deletions temporalcli/commands.activity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,16 @@ func (s *SharedServerSuite) TestActivityCommandFailed_NoActivityTpeOrId() {
}
}

func (s *SharedServerSuite) TestActivityCommandFailed_BothActivityTpeOrId() {
run := s.waitActivityStarted()

commands := []string{"pause", "unpause", "reset"}
for _, command := range commands {
res := sendActivityCommand(command, run, s, "--activity-id", activityId, "--activity-type", activityType)
s.Error(res.Err)
}
}

func (s *SharedServerSuite) TestActivityReset() {
run := s.waitActivityStarted()

Expand Down
38 changes: 32 additions & 6 deletions temporalcli/commands.gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
package temporalcli

import (
"fmt"

"github.com/mattn/go-isatty"

"github.com/spf13/cobra"
Expand Down Expand Up @@ -473,10 +475,35 @@ func NewTemporalActivityFailCommand(cctx *CommandContext, parent *TemporalActivi
return &s
}

type ActivityReferenceOptions struct {
ActivityId string
ActivityType string
}

func (v *ActivityReferenceOptions) buildFlags(_ *CommandContext, f *pflag.FlagSet, activityType string, onlyWithoutQuery bool) {
Comment thread
spkane31 marked this conversation as resolved.
Outdated
f.StringVarP(&v.ActivityId, "activity-id", "a", "", fmt.Sprintf("Activity ID to %s.", activityType))
if onlyWithoutQuery {
f.StringVarP(&v.ActivityType, "activity-type", "g", "", fmt.Sprintf("Activity Type to %s. Can only be used without --query.", activityType))
} else {
f.StringVarP(&v.ActivityType, "activity-type", "g", "", fmt.Sprintf("Activity Type to %s.", activityType))
}
}

func (v *ActivityReferenceOptions) validateFlags() error {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

You can't add code to this code-generated file, it'd get removed on regen. Rather, add in another file (or maybe better, do not add methods to generated structures beyond the run method needed on command, but make simple utility functions that accept them).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Removed the ActivityReferenceOptions struct entirely, opting for the repetitive checking. The flags for this activity-id and activity-type are already set with other option-sets which causes a panic and unraveling that doesn't seem like the correct solution here.

cc @ychebotarev

if v.ActivityId != "" && v.ActivityType != "" {
return fmt.Errorf("either Activity Type or Activity Id, but not both")
}
if v.ActivityId == "" && v.ActivityType == "" {
return fmt.Errorf("either Activity Type or Activity Id, but not both")
}
return nil
}

type TemporalActivityPauseCommand struct {
Parent *TemporalActivityCommand
Command cobra.Command
WorkflowReferenceOptions
ActivityReferenceOptions
ActivityId string
ActivityType string
Identity string
Expand All @@ -494,10 +521,9 @@ func NewTemporalActivityPauseCommand(cctx *CommandContext, parent *TemporalActiv
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\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.")
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.ActivityReferenceOptions.buildFlags(cctx, s.Command.Flags(), "pause", false)
s.Command.Run = func(c *cobra.Command, args []string) {
if err := s.run(cctx, args); err != nil {
cctx.Options.Fail(err)
Expand All @@ -510,6 +536,7 @@ type TemporalActivityResetCommand struct {
Parent *TemporalActivityCommand
Command cobra.Command
WorkflowReferenceOptions
ActivityReferenceOptions
ActivityId string
ActivityType string
Identity string
Expand All @@ -529,12 +556,11 @@ func NewTemporalActivityResetCommand(cctx *CommandContext, parent *TemporalActiv
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.")
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.")
s.WorkflowReferenceOptions.buildFlags(cctx, s.Command.Flags())
s.ActivityReferenceOptions.buildFlags(cctx, s.Command.Flags(), "reset", false)
s.Command.Run = func(c *cobra.Command, args []string) {
if err := s.run(cctx, args); err != nil {
cctx.Options.Fail(err)
Expand All @@ -547,6 +573,7 @@ type TemporalActivityUnpauseCommand struct {
Parent *TemporalActivityCommand
Command cobra.Command
SingleWorkflowOrBatchOptions
ActivityReferenceOptions
ActivityId string
ActivityType string
Identity string
Expand All @@ -568,15 +595,14 @@ func NewTemporalActivityUnpauseCommand(cctx *CommandContext, parent *TemporalAct
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\nActivities can be unpaused in bulk via a visibility Query list filter:\n\n```\ntemporal activity unpause \\\n --query YourQuery \\\n --reason YourReasonForTermination\n```\n\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 unpause. Can only be used without --query.")
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.")
s.Command.Flags().BoolVar(&s.MatchAll, "match-all", false, "Every paused activity should be unpaused. This flag is ignored if activity-type is provided. Can only be used with --query.")
s.Jitter = 0
s.Command.Flags().VarP(&s.Jitter, "jitter", "j", "The activity will start at random a time within the specified duration. Can only be used with --query.")
s.SingleWorkflowOrBatchOptions.buildFlags(cctx, s.Command.Flags())
s.ActivityReferenceOptions.buildFlags(cctx, s.Command.Flags(), "unpause", true)
s.Command.Run = func(c *cobra.Command, args []string) {
if err := s.run(cctx, args); err != nil {
cctx.Options.Fail(err)
Expand Down
16 changes: 10 additions & 6 deletions temporalcli/commandsgen/commands.yml
Original file line number Diff line number Diff line change
Expand Up @@ -444,16 +444,17 @@ commands:
- name: activity-id
short: a
type: string
description: Activity ID to pause.
description: Activity ID to pause. Either `activity-id` or `activity-type` must be provided, but not both.
- name: activity-type
short: g
type: string
description: Activity Type to pause.
description: Either `activity-id` or `activity-type` must be provided, but not both.Activity Type to pause.
- name: identity
type: string
description: Identity of the user submitting this request.
option-sets:
- workflow reference
- activity-reference

- name: temporal activity unpause
summary: Unpause an Activity
Expand Down Expand Up @@ -498,11 +499,12 @@ commands:
short: a
type: string
description: |
Activity ID to unpause. Can only be used without --query.
Activity ID to unpause. Can only be used without --query or --match-all. Either `activity-id` or `activity-type` must be provided, but not both.
- name: activity-type
short: g
type: string
description: Activity Type to unpause.
description: |
Activity Type to unpause. Can only be used without --match-all. Either `activity-id` or `activity-type` must be provided, but not both.
- name: identity
type: string
description: Identity of the user submitting this request.
Expand All @@ -526,6 +528,7 @@ commands:
Can only be used with --query.
option-sets:
- single-workflow-or-batch
- activity-reference

- name: temporal activity reset
summary: Reset an Activity
Expand Down Expand Up @@ -558,11 +561,11 @@ commands:
- name: activity-id
short: a
type: string
description: Activity ID to pause.
description: Activity ID to reset. Either `activity-id` or `activity-type` must be provided, but not both.
- name: activity-type
short: g
type: string
description: Activity Type to pause.
description: Activity Type to reset. Either `activity-id` or `activity-type` must be provided, but not both.
- name: identity
type: string
description: Identity of the user submitting this request.
Expand All @@ -574,6 +577,7 @@ commands:
description: Reset the Activity's heartbeat.
option-sets:
- workflow reference
- activity-reference

- name: temporal batch
summary: Manage running batch jobs
Expand Down
Loading