Skip to content

Conversation

@vaibhavyadav-dev
Copy link
Contributor

@vaibhavyadav-dev vaibhavyadav-dev commented Aug 19, 2025

What changed?

Added an admin command that dump all frontend dynamic config values,

Why?

Operators currently cannot easily inspect frontend runtime dynamic configuration, dumping values aids troubleshooting, incident response, and verification after config changes.

How did you test it?

  • built
  • run locally and tested manually
  • covered by existing tests
  • added new unit test(s)
  • added new functional test(s)

Closes #421

@vaibhavyadav-dev vaibhavyadav-dev requested a review from a team as a code owner August 19, 2025 20:15
@dnr
Copy link
Contributor

dnr commented Aug 19, 2025

This isn't dumping all dynamic config values, it's only dumping the frontend config, and only for one particular (nonexistent) namespace. To do this properly you'd need to add support in the dynamicconfig.Client interface, but I'm not sure we want to do that. We could support getting the value of a single key by name without changing the interface.

What are you actually trying to use this for?

@bergundy
Copy link
Member

@dnr, @vaibhavyadav-dev joined the community slack and volunteered to contribute. I gave him this issue since I knew there's been a longstanding ask to add this API.

100% agree with the feedback so far. I can guide from here.

Copy link
Member

@bergundy bergundy left a comment

Choose a reason for hiding this comment

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

You are going to want to also add a ListKeys() method to the dynamic config client.

@dnr do you think this is a reasonable request?


rpc ForceUnloadTaskQueuePartition (ForceUnloadTaskQueuePartitionRequest) returns (ForceUnloadTaskQueuePartitionResponse) {}

rpc GetConfigurations(GetConfigurationsRequest) returns (GetConfigurationsResponse) {}
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
rpc GetConfigurations(GetConfigurationsRequest) returns (GetConfigurationsResponse) {}
rpc GetConfiguration(GetConfigurationRequest) returns (GetConfigurationResponse) {}

Comment on lines 607 to 608
message GetConfigurationsRequest {}
message GetConfigurationsResponse{
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
message GetConfigurationsRequest {}
message GetConfigurationsResponse{
message GetConfigurationRequest {}
message GetConfigurationResponse {

Copy link
Contributor

Choose a reason for hiding this comment

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

Please make all this stuff have the string "DynamicConfig" in it. There are two types of configuration and we should be explicit to avoid confusion. (I would even prefer GetDynamicConfig to GetDynamicConfiguration since that's how it's referred to all over the code.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

okay

Comment on lines 609 to 610
string cluster_name = 1;
map<string, google.protobuf.Value> config_values = 2;
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
string cluster_name = 1;
map<string, google.protobuf.Value> config_values = 2;
repeated HostConfig host_config = 1;

And add a HostConfig message that will embed structured config via a struct:

message HostConfig {
  // The host that this configuration was loaded from.
  string hostname = 1;
  // The raw dynamic config loaded with all constraints.
  google.protobuf.Struct raw_dynamic_config = 2;
}

@dnr
Copy link
Contributor

dnr commented Aug 19, 2025

You are going to want to also add a ListKeys() method to the dynamic config client.

@dnr do you think this is a reasonable request?

I would rather not. I don't think we should add methods there without a very good reason, and I don't feel like this is it. I think we should support a single key query to start and then see if it satisfies people's use case. (Tbh I'm skeptical this is even useful at all but I guess it doesn't hurt.)

The problem is that it'll break the build for anyone with a custom Client until they add support. Also just ListKeys plus calling GetValue on each key is racy (a key may be added or removed between the List and the Get). So you want to get a snapshot of the whole state, but that may be expensive.

If we really do need to do that, we should add it as optional (i.e. interface-assert it when needed) to not interfere with existing Clients.

@vaibhavyadav-dev vaibhavyadav-dev changed the title add command to dump dynamic config values added command to dump frontend dynamic config values Aug 22, 2025
@bergundy
Copy link
Member

If we really do need to do that, we should add it as optional (i.e. interface-assert it when needed) to not interfere with existing Clients.

Curious if there are known client implementations that we would be concerned with here or if this is mostly speculation.
Agree that the interface assert would be cleaner.
100% can go with a Snapshot() method if needed. I think that would be a reasonable approach.
I'm thinking that this API would be good for debugging, I would want this to evolve to a point where we could potentially spot misaligned configurations between the nodes and it may come in handy for when we migrate between self-hosted and cloud.

@bergundy
Copy link
Member

bergundy commented Sep 2, 2025

Lets make GetConfigurationRequest take a repeated string dynamic_config_keys and make the response include the repeated HostConfig as I've mentioned before but only for the current host, no need to fan out for now.

You will need to copy the definition of Constraints from common/dynamicconfig/client.go to proto/internal/temporal/server/api/config/v1/message.proto along with HostConfig and ConstrainedValue detailed below:

message ConstrainedValue {
  Constraints constraints = 1;
  google.protobuf.Struct value = 2;
}

message HostConfig {
  // The host that this configuration was loaded from.
  string hostname = 1;
  // The raw dynamic config loaded with all constraints.
  map<string, ConstrainedValue> dynamic_config = 2;
}

@bergundy
Copy link
Member

Sorry if I mislead you, each config name may have multiple constrained values, this would be a better representation:

message ConstrainedValue {
  Constraints constraints = 1;
  google.protobuf.Struct value = 2;
}

message ConstrainedValues {
  repeated ConstrainedValue items = 1;
}

message HostConfig {
  // The host that this configuration was loaded from.
  string hostname = 1;
  // The raw dynamic config loaded with all constraints.
  map<string, ConstrainedValues> dynamic_config = 2;
}

@vaibhavyadav-dev vaibhavyadav-dev force-pushed the added-tdbg-command-to-dump-dynamic-config-values branch from e90aa6c to adbce8b Compare September 22, 2025 19:29
@bergundy bergundy changed the title added command to dump frontend dynamic config values Add command to dump frontend dynamic config values Sep 27, 2025
Comment on lines 608 to 625
message Constraints {
string namespace = 1;
string namespace_id = 2;
string task_queue_name = 3;
int32 task_queue_type = 4;
int32 shard_id = 5;
int32 task_type = 6;
string destination = 7;
}

message ConstrainedValue {
Constraints constraints = 1;
google.protobuf.Struct value = 2;
}

message ConstrainedValues {
repeated ConstrainedValue items = 1;
}
Copy link
Member

Choose a reason for hiding this comment

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

You can put this in proto/internal/temporal/server/api/dynamicconfig/v1/message.proto.


rpc ForceUnloadTaskQueuePartition (ForceUnloadTaskQueuePartitionRequest) returns (ForceUnloadTaskQueuePartitionResponse) {}

rpc GetDynamicConfigurations(GetDynamicConfigurationsRequest) returns (GetDynamicConfigurationsResponse) {}
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
rpc GetDynamicConfigurations(GetDynamicConfigurationsRequest) returns (GetDynamicConfigurationsResponse) {}
rpc GetHostConfiguration(GetHostConfigurationRequest) returns (GetHostConfigurationResponse) {}

pageSize := 100
var nextPageToken []byte

namespaces := make([]string, 0)
Copy link
Member

Choose a reason for hiding this comment

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

You don't need to get the list of namespaces to implement this feature.

Comment on lines 2216 to 2221
constrainedValues := adh.getConstrainedValueForKey(key, namespaces)
if len(constrainedValues) > 0 {
dynamicConfig[key] = &adminservice.ConstrainedValues{
Items: constrainedValues,
}
}
Copy link
Member

Choose a reason for hiding this comment

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

This would just be:

dcClient.GetValue(key)

Just make sure you have access to a dynamicconfig.Client instance in this handler.

@vaibhavyadav-dev vaibhavyadav-dev requested a review from a team as a code owner November 14, 2025 18:00
@vaibhavyadav-dev vaibhavyadav-dev force-pushed the added-tdbg-command-to-dump-dynamic-config-values branch from 36962cc to 2cd597c Compare November 21, 2025 04:50
@vaibhavyadav-dev
Copy link
Contributor Author

Closing this PR; opening a fresh one with a cleaner commit history.
New PR

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.

Add admin command to dump dynamic config value[s]

3 participants