Skip to content

Commit db5f475

Browse files
Veeral Patelclaude
authored andcommitted
feat: add tdbg taskqueue get-user-data command
Adds AdminService.GetTaskQueueUserData proto + generated code, and wires it up as a tdbg command. Accepts --task-queue (required), --task-queue-type (default: workflow), and --partition-id (default: 0). The backend handler implementation is in a separate PR. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 94556cc commit db5f475

4 files changed

Lines changed: 123 additions & 0 deletions

File tree

client/admin/client_gen.go

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tools/tdbg/task_queue_commands.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,50 @@ func AdminDescribeTaskQueuePartition(c *cli.Context, clientFactory ClientFactory
182182
return nil
183183
}
184184

185+
// AdminGetTaskQueueUserData returns the per-type user data for a task queue partition
186+
func AdminGetTaskQueueUserData(c *cli.Context, clientFactory ClientFactory) error {
187+
namespace, err := getRequiredOption(c, FlagNamespace)
188+
if err != nil {
189+
return err
190+
}
191+
192+
tqName, err := getRequiredOption(c, FlagTaskQueue)
193+
if err != nil {
194+
return err
195+
}
196+
197+
tlTypeInt, err := StringToEnum(c.String(FlagTaskQueueType), enumspb.TaskQueueType_value)
198+
if err != nil {
199+
return fmt.Errorf("invalid task queue type: %w", err)
200+
}
201+
tqType := enumspb.TaskQueueType(tlTypeInt)
202+
if tqType == enumspb.TASK_QUEUE_TYPE_UNSPECIFIED {
203+
return errors.New("invalid task queue type") // nolint
204+
}
205+
206+
partitionID := 0
207+
if c.IsSet(FlagPartitionID) {
208+
partitionID = c.Int(FlagPartitionID)
209+
}
210+
211+
client := clientFactory.AdminClient(c)
212+
req := &adminservice.GetTaskQueueUserDataRequest{
213+
Namespace: namespace,
214+
TaskQueue: tqName,
215+
TaskQueueType: tqType,
216+
PartitionId: int32(partitionID),
217+
}
218+
219+
ctx, cancel := newContext(c)
220+
defer cancel()
221+
if response, e := client.GetTaskQueueUserData(ctx, req); e != nil {
222+
return fmt.Errorf("unable to get Task Queue User Data: %w", e)
223+
} else {
224+
prettyPrintJSONObject(c, response)
225+
}
226+
return nil
227+
}
228+
185229
// AdminForceUnloadTaskQueuePartition forcefully unloads a task queue partition
186230
func AdminForceUnloadTaskQueuePartition(c *cli.Context, clientFactory ClientFactory) error {
187231
// extracting the namespace

tools/tdbg/task_queue_commands_test.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ type (
1919
adminservice.AdminServiceClient
2020
describeTaskQueuePartitionFn func(request *adminservice.DescribeTaskQueuePartitionRequest) (*adminservice.DescribeTaskQueuePartitionResponse, error)
2121
forceUnloadTaskQueuePartitionFn func(request *adminservice.ForceUnloadTaskQueuePartitionRequest) (*adminservice.ForceUnloadTaskQueuePartitionResponse, error)
22+
getTaskQueueUserDataFn func(request *adminservice.GetTaskQueueUserDataRequest) (*adminservice.GetTaskQueueUserDataResponse, error)
2223
}
2324
)
2425

@@ -82,6 +83,10 @@ func (t *testClient) ForceUnloadTaskQueuePartition(_ context.Context, request *a
8283
return t.forceUnloadTaskQueuePartitionFn(request)
8384
}
8485

86+
func (t *testClient) GetTaskQueueUserData(_ context.Context, request *adminservice.GetTaskQueueUserDataRequest, opts ...grpc.CallOption) (*adminservice.GetTaskQueueUserDataResponse, error) {
87+
return t.getTaskQueueUserDataFn(request)
88+
}
89+
8590
func (s *taskQueueCommandTestSuite) SetupTest() {
8691
s.Assertions = require.New(s.T())
8792
s.controller = gomock.NewController(s.T())
@@ -94,6 +99,9 @@ func (s *taskQueueCommandTestSuite) SetupTest() {
9499
forceUnloadTaskQueuePartitionFn: func(request *adminservice.ForceUnloadTaskQueuePartitionRequest) (*adminservice.ForceUnloadTaskQueuePartitionResponse, error) {
95100
return &adminservice.ForceUnloadTaskQueuePartitionResponse{}, nil
96101
},
102+
getTaskQueueUserDataFn: func(request *adminservice.GetTaskQueueUserDataRequest) (*adminservice.GetTaskQueueUserDataResponse, error) {
103+
return &adminservice.GetTaskQueueUserDataResponse{}, nil
104+
},
97105
}
98106
s.app = NewCliApp(func(params *Params) {
99107
params.ClientFactory = client
@@ -163,3 +171,40 @@ func (s *taskQueueCommandTestSuite) TestForceUnloadTaskQueuePartition() {
163171
}
164172
}
165173
}
174+
175+
// TestGetTaskQueueUserData tests that the cli accepts the various arguments for get-user-data.
176+
func (s *taskQueueCommandTestSuite) TestGetTaskQueueUserData() {
177+
baseCommand := []string{"tdbg", "taskqueue", "get-user-data",
178+
"--task-queue", "test"}
179+
180+
// Run shared test cases, skipping sticky-name (not a registered flag on this command).
181+
for _, test := range testCases {
182+
if len(test.inputFlags) > 0 && test.inputFlags[0] == "--sticky-name" {
183+
continue
184+
}
185+
cliCommand := append(baseCommand, test.inputFlags...)
186+
resp := s.app.Run(cliCommand)
187+
if resp != nil {
188+
s.ErrorContainsf(resp, test.err.Error(), "error present")
189+
}
190+
}
191+
192+
// Missing --task-queue is enforced by cli/v2 (Required: true) before the action runs.
193+
s.Error(s.app.Run([]string{"tdbg", "taskqueue", "get-user-data"}))
194+
195+
// No --task-queue-type or --partition-id: both use their defaults and succeed.
196+
s.NoError(s.app.Run([]string{"tdbg", "taskqueue", "get-user-data",
197+
"--task-queue", "test"}))
198+
199+
// Matching client returns an error: CLI wraps and returns it.
200+
errorClient := &testClient{
201+
getTaskQueueUserDataFn: func(request *adminservice.GetTaskQueueUserDataRequest) (*adminservice.GetTaskQueueUserDataResponse, error) {
202+
return nil, errors.New("matching unavailable")
203+
},
204+
}
205+
errorApp := NewCliApp(func(params *Params) { params.ClientFactory = errorClient })
206+
errorApp.ExitErrHandler = func(context *cli.Context, err error) {}
207+
resp := errorApp.Run([]string{"tdbg", "taskqueue", "get-user-data",
208+
"--task-queue", "test"})
209+
s.ErrorContains(resp, "unable to get Task Queue User Data")
210+
}

tools/tdbg/tdbg_commands.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,30 @@ func newAdminTaskQueueCommands(clientFactory ClientFactory) []*cli.Command {
682682
return AdminForceUnloadTaskQueuePartition(c, clientFactory)
683683
},
684684
},
685+
{
686+
Name: "get-user-data",
687+
Usage: "Get per-type user data stored for a task queue",
688+
Flags: []cli.Flag{
689+
&cli.StringFlag{
690+
Name: FlagTaskQueue,
691+
Usage: "Task Queue name",
692+
Required: true,
693+
},
694+
&cli.StringFlag{
695+
Name: FlagTaskQueueType,
696+
Value: "TASK_QUEUE_TYPE_WORKFLOW",
697+
Usage: "Task Queue type: TASK_QUEUE_TYPE_WORKFLOW, TASK_QUEUE_TYPE_ACTIVITY, TASK_QUEUE_TYPE_NEXUS",
698+
},
699+
&cli.Int64Flag{
700+
Name: FlagPartitionID,
701+
Usage: "Partition ID to fetch user data from (default 0 = root partition)",
702+
Value: 0,
703+
},
704+
},
705+
Action: func(c *cli.Context) error {
706+
return AdminGetTaskQueueUserData(c, clientFactory)
707+
},
708+
},
685709
}
686710
}
687711

0 commit comments

Comments
 (0)