[ https://issues.apache.org/jira/browse/CASSANDRA-15254?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17685622#comment-17685622 ]
Maxim Muzafarov commented on CASSANDRA-15254: --------------------------------------------- [~dcapwell], I think I caught the tone of your concern, let me organise what you have said and propose a solution that might fit our case. Please correct me if I'm wrong somewhere, I just don't know the full history of the reasons for the changes that have happened to make the Config class better. There are only three types of node configuration properties represented as Config's fields that we should think of: * {_}The old property names, @Replaces(oldName = "cross_node_timeout"){_}. These properties exist for backward compatibility and are loaded from the persisted configuration yaml file. Once such a property is loaded, its old name is no longer available at runtime for usage, right? Since old names are not used at runtime and exist only in persisted files, it is correct not to have setter and getter methods for them in the DatabaseDescriptor class. * {_}The properties that are NOT changed at runtime{_}. An example of such a property might be Config.cluster_name or Config.storage_port. These types of properties are not changed during a node lifecycle and MUST NOT be changed at runtime. * _The properties that can be changed at runtime_ and are responsible for managing a node's internal processes or state during the node lifecycle. To enable configuration management we have to answer the following main question: _*How can we determine at runtime which of the properties we can and can't change during a node run?*_ No matter how we intend to update a particular property using the setter method or reflection, it's currently impossible to determine from the source code we have whether that property is updatable or not. This leads me to the following mutually exclusive solutions to the above question: # Maintain this information in a separate data structure. To associate a field name with its method name, this is my option 1 and the purpose of the SetterWalker class; # Enforce the contract between the filed name and the setter method name, with the field type and the method input type. It differs now for almost everything - setRepairRpcTimeout and repair_request_timeout, but we must have setRepairRequestTimeout and repair_request_timeout to ensure the field is changeable; # Annotate either method by the field name or the field by the setter's method name. This requires a LOT of tedious changes and makes everything more fragile when renaming happens. I immediately discarded this option once I thought. Previously, I have shared the possible way of maintaining a dedicated data structure (the option #1) with the helper util class to avoid most of the manual work. However, taking all your concerns into account, we can also go through the process of enforcing a field name and method name contract, and it will look like this: * Include the generating process of ConfigFields constants into the build. This will force us to handle any changes to field names in the Config through the source code, we will not miss any changes to those that are used. * Enforce the contract for the config's field name and its setter (optionally getter) method. This allows us to determine which properties we can change at runtime. If a property has a corresponding setter method, this means we can change it at runtime. We may have a method that doesn't match the field name, which would mean we can change the field, but not through the public API (JMX, SettingsTable). * Getting and setting fields in the Config class is done by {{org.yaml.snakeyaml.introspector.Property}} in the ConfigurationRegistry, as you suggested in the comments earlier; So, the DatabaseDescriptor will look like this: {code:java} public class DatabaseDescriptor { public static long getRepairRpcTimeout(TimeUnit unit) { return getRepairRequestTimeout().to(unit); } public static void setRepairRpcTimeout(Long timeOutInMillis) { setRepairRequestTimeout(new DurationSpec.LongMillisecondsBound(timeOutInMillis)); } public static DurationSpec.LongMillisecondsBound getRepairRequestTimeout() { return ConfigurationRegistry.instance.get(ConfigFields.REPAIR_REQUEST_TIMEOUT); } public static void setRepairRequestTimeout(DurationSpec.LongMillisecondsBound bound) { ConfigurationRegistry.instance.update(ConfigFields.REPAIR_REQUEST_TIMEOUT, bound); } } {code} Once we have knowledge which of properties can change at runtime, we will be able to deal with a problem raised and mentioned here by Ekaterina Dimitrova - CASSANDRA-17735. We will be able to remove annoying MBean classes and create them dynamically at a node startup (or new ones) based on this knowledge, so that no one will face this problem again in the future. WDYT? > Allow UPDATE on settings virtual table to change running configurations > ----------------------------------------------------------------------- > > Key: CASSANDRA-15254 > URL: https://issues.apache.org/jira/browse/CASSANDRA-15254 > Project: Cassandra > Issue Type: New Feature > Components: Feature/Virtual Tables > Reporter: Chris Lohfink > Assignee: Maxim Muzafarov > Priority: Normal > Attachments: Configuration Registry Diagram.png > > Time Spent: 0.5h > Remaining Estimate: 0h > > Allow using UPDATE on the system_views.settings virtual table to update > configs at runtime for the equivalent of the dispersed JMX > attributes/operations. -- This message was sent by Atlassian Jira (v8.20.10#820010) --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org For additional commands, e-mail: commits-h...@cassandra.apache.org