[ 
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

Reply via email to