Skip to content

HBASE-29841: Split bulky ReadOnlyController into multiple smaller controllers - #7661

Merged
anmolnar merged 2 commits into
apache:HBASE-29081from
sharmaar12:dyn_cop_reg
Feb 6, 2026
Merged

HBASE-29841: Split bulky ReadOnlyController into multiple smaller controllers#7661
anmolnar merged 2 commits into
apache:HBASE-29081from
sharmaar12:dyn_cop_reg

Conversation

@sharmaar12

Copy link
Copy Markdown
Contributor

Currently we have created a single ReadOnlyController which needs to get added as coprocessor for master, region and region server. In this task we will be breaking ReadOnlyController into multiple smaller controller to avoid unnecessarily adding methods which are not relevant for particular role for example, master copocessor should only register methods which may run on master and not on region or region server.

@sharmaar12
sharmaar12 marked this pull request as ready for review January 23, 2026 04:46
@Apache-HBase

This comment has been minimized.

@Apache-HBase

This comment has been minimized.

@wchevreuilwchevreuil left a comment

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.

LGTM, just have few nits.

return Optional.of(this);
}

/* ---- ConfigurationObserver Overrides ---- */

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.

nit: remove this comment and add @Override annotation.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done.

HConstants.HBASE_GLOBAL_READONLY_ENABLED_KEY, this.globalReadOnlyEnabled);
}

/* ---- BulkLoadObserver Overrides ---- */

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.

nit: remove this comment.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done.

return Optional.of(this);
}

/* ---- ConfigurationObserver Overrides ---- */

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.

nit: remove this comment and add @Override annotation.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done.

if (!isOnMeta(c)) {
internalReadOnlyGuard();
/* ---- ConfigurationObserver Overrides ---- */
public void onConfigurationChange(Configuration conf) {

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.

nit: remove this comment and add @Override annotation.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done.

return Optional.of(this);
}

/* ---- MasterObserver Overrides ---- */

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.

nit: remove this comment.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done.

}

/* ---- ConfigurationObserver Overrides ---- */
public void onConfigurationChange(Configuration conf) {

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.

nit: remove this comment and add @Override annotation.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done.

HConstants.HBASE_GLOBAL_READONLY_ENABLED_KEY, this.globalReadOnlyEnabled);
}

/* ---- RegionServerObserver Overrides ---- */

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.

nit: remove this comment.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done.

}

/* ---- ConfigurationObserver Overrides ---- */
public void onConfigurationChange(Configuration conf) {

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.

nit: remove this comment and add @Override annotation.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done.

}
}

/* ---- RegionObserver Overrides ---- */

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.

nit: remove this comment.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done.

…trollers
Currently we have created a single ReadOnlyController which needs to get added as coprocessor for master, region and region server. In this task we will be breaking ReadOnlyController into multiple smaller controller to avoid unnecessarily adding methods which are not relevant for particular role for example, master copocessor should only register methods which may run on master and not on region or region server.
@Apache-HBase

This comment has been minimized.

@Apache-HBase

This comment has been minimized.

@kgeiszkgeisz left a comment

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.

I have a few comments, but it LGTM overall.

private static final Logger LOG = LoggerFactory.getLogger(BulkLoadReadOnlyController.class);
private volatile boolean globalReadOnlyEnabled;

private void internalReadOnlyGuard() throws DoNotRetryIOException {

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.

I noticed there are come common methods among these different types of ReadOnlyController classes. The ones I noticed are internalReadOnlyGuard(), start(), stop(), and onConfigurationChange(). I see the MasterReadOnlyController class has some different implementations for start() and onConfigurationChange(), but the other methods seem roughly the same for each class. Do you think it would make sense to have some kind of ReadOnlyControllerBase class that defines these methods and MasterReadOnlyController can override anything that needs to be implemented differently?

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.

I totally agree. A common base class would definitely make sense.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Thanks for the suggestion. I will create the AbstractReadOnlyController class which implements ConfigurationObserver so that we can move start(), stop(), OnConfigurationChange() and internalReadOnlyGuard().

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done.

internalReadOnlyGuard();
RegionObserver.super.preCommitStoreFile(ctx, family, pairs);
}
private void manageActiveClusterIdFile(boolean newValue) {

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.

nit: Can we change newValue to something like isEnablingReadOnly (or similar)? When I first saw newValue, it made me think this newValue was being used to assign its value to something. However, it looks like it's just used to determine what we are doing with the active cluster file.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done.

public void onConfigurationChange(Configuration conf) {
boolean maybeUpdatedConfValue = conf.getBoolean(HConstants.HBASE_GLOBAL_READONLY_ENABLED_KEY,
HConstants.HBASE_GLOBAL_READONLY_ENABLED_DEFAULT);
if (this.globalReadOnlyEnabled != maybeUpdatedConfValue) {

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.

Is there a reason why this implementation of onConfigurationChange() has the if (this.globalReadOnlyEnabled != maybeUpdatedConfValue) block while the other implementations of this method don't? We may want this if block in each method to prevent extra logging when nothing was actually changed.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Agreed. Will update the code accordingly.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done.

@anmolnaranmolnar left a comment

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.

Overall looks good to me. Please address @kgeisz 's suggestion.
The split looks good, but are we going to set this up in HBase. Do we need to set the controllers individually in the config or are you planning to implement an on/off switch to make it easier in a later patch?

@sharmaar12

Copy link
Copy Markdown
ContributorAuthor

Overall looks good to me. Please address @kgeisz 's suggestion. The split looks good, but are we going to set this up in HBase. Do we need to set the controllers individually in the config or are you planning to implement an on/off switch to make it easier in a later patch?

We don't need to set that individually, instead we will be registering them at the time of initialization depending on the value of the property hbase.global.readonly.supported. This will get introduced as part of HBASE-29756)

@Apache-HBase

Copy link
Copy Markdown

💔 -1 overall

VoteSubsystemRuntimeLogfileComment
+0 🆗reexec0m 38sDocker mode activated.
_ Prechecks _
+1 💚dupname0m 0sNo case conflicting files found.
+0 🆗codespell0m 0scodespell was not available.
+0 🆗detsecrets0m 0sdetect-secrets was not available.
+1 💚@author0m 0sThe patch does not contain any @author tags.
+1 💚hbaseanti0m 0sPatch does not have any anti-patterns.
_ HBASE-29081 Compile Tests _
+1 💚mvninstall3m 44sHBASE-29081 passed
+1 💚compile3m 41sHBASE-29081 passed
-0 ⚠️checkstyle0m 15s/buildtool-branch-checkstyle-hbase-server.txtThe patch fails to run checkstyle in hbase-server
+1 💚spotbugs1m 46sHBASE-29081 passed
+1 💚spotless0m 56sbranch has no errors when running spotless:check.
_ Patch Compile Tests _
+1 💚mvninstall3m 19sthe patch passed
+1 💚compile3m 35sthe patch passed
+1 💚javac3m 35sthe patch passed
+1 💚blanks0m 0sThe patch has no blanks issues.
-0 ⚠️checkstyle0m 13s/buildtool-patch-checkstyle-hbase-server.txtThe patch fails to run checkstyle in hbase-server
+1 💚spotbugs1m 45sthe patch passed
+1 💚hadoopcheck12m 23sPatch does not cause any errors with Hadoop 3.3.6 3.4.0.
-1 ❌spotless0m 40spatch has 21 errors when running spotless:check, run spotless:apply to fix.
_ Other Tests _
+1 💚asflicense0m 10sThe patch does not generate ASF License warnings.
41m 8s
SubsystemReport/Notes
DockerClientAPI=1.43 ServerAPI=1.43 base: https://ci-hbase.apache.org/job/HBase-PreCommit-GitHub-PR/job/PR-7661/3/artifact/yetus-general-check/output/Dockerfile
GITHUB PR#7661
JIRA IssueHBASE-29841
Optional Testsdupname asflicense javac spotbugs checkstyle codespell detsecrets compile hadoopcheck hbaseanti spotless
unameLinux a730e0a865a1 5.4.0-1103-aws #111~18.04.1-Ubuntu SMP Tue May 23 20:04:10 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
Build toolmaven
Personalitydev-support/hbase-personality.sh
git revisionHBASE-29081 / 6a4486d
Default JavaEclipse Adoptium-17.0.11+9
spotlesshttps://ci-hbase.apache.org/job/HBase-PreCommit-GitHub-PR/job/PR-7661/3/artifact/yetus-general-check/output/patch-spotless.txt
Max. process+thread count85 (vs. ulimit of 30000)
modulesC: hbase-server U: hbase-server
Console outputhttps://ci-hbase.apache.org/job/HBase-PreCommit-GitHub-PR/job/PR-7661/3/console
versionsgit=2.34.1 maven=3.9.8 spotbugs=4.7.3
Powered byApache Yetus 0.15.0 https://yetus.apache.org

This message was automatically generated.

@Apache-HBase

Copy link
Copy Markdown

💔 -1 overall

VoteSubsystemRuntimeLogfileComment
+0 🆗reexec1m 50sDocker mode activated.
-0 ⚠️yetus0m 3sUnprocessed flag(s): --brief-report-file --spotbugs-strict-precheck --author-ignore-list --blanks-eol-ignore-file --blanks-tabs-ignore-file --quick-hadoopcheck
_ Prechecks _
_ HBASE-29081 Compile Tests _
+1 💚mvninstall2m 35sHBASE-29081 passed
+1 💚compile0m 45sHBASE-29081 passed
+1 💚javadoc0m 22sHBASE-29081 passed
+1 💚shadedjars4m 35sbranch has no errors when building our shaded downstream artifacts.
_ Patch Compile Tests _
+1 💚mvninstall2m 15sthe patch passed
+1 💚compile0m 45sthe patch passed
+1 💚javac0m 45sthe patch passed
+1 💚javadoc0m 20sthe patch passed
+1 💚shadedjars4m 30spatch has no errors when building our shaded downstream artifacts.
_ Other Tests _
-1 ❌unit225m 34s/patch-unit-hbase-server.txthbase-server in the patch failed.
247m 19s
SubsystemReport/Notes
DockerClientAPI=1.48 ServerAPI=1.48 base: https://ci-hbase.apache.org/job/HBase-PreCommit-GitHub-PR/job/PR-7661/3/artifact/yetus-jdk17-hadoop3-check/output/Dockerfile
GITHUB PR#7661
JIRA IssueHBASE-29841
Optional Testsjavac javadoc unit compile shadedjars
unameLinux 6b52b40bd1c1 6.8.0-1024-aws #26~22.04.1-Ubuntu SMP Wed Feb 19 06:54:57 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
Build toolmaven
Personalitydev-support/hbase-personality.sh
git revisionHBASE-29081 / 6a4486d
Default JavaEclipse Adoptium-17.0.11+9
Test Resultshttps://ci-hbase.apache.org/job/HBase-PreCommit-GitHub-PR/job/PR-7661/3/testReport/
Max. process+thread count7261 (vs. ulimit of 30000)
modulesC: hbase-server U: hbase-server
Console outputhttps://ci-hbase.apache.org/job/HBase-PreCommit-GitHub-PR/job/PR-7661/3/console
versionsgit=2.34.1 maven=3.9.8
Powered byApache Yetus 0.15.0 https://yetus.apache.org

This message was automatically generated.

@anmolnaranmolnar left a comment

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.

lgtm. Thanks for the refactoring.

@kgeiszkgeisz left a comment

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.

LGTM

@anmolnar
anmolnar merged commit fc4ed96 into apache:HBASE-29081Feb 6, 2026
1 check failed
@sharmaar12
sharmaar12 deleted the dyn_cop_reg branch February 12, 2026 15:13
anmolnar pushed a commit that referenced this pull request Mar 13, 2026
…trollers (#7661)
* HBASE-29841: Split bulky ReadOnlyController into multiple smaller controllers
Currently we have created a single ReadOnlyController which needs to get added as coprocessor for master, region and region server. In this task we will be breaking ReadOnlyController into multiple smaller controller to avoid unnecessarily adding methods which are not relevant for particular role for example, master copocessor should only register methods which may run on master and not on region or region server.
* Addres review Comments
anmolnar pushed a commit that referenced this pull request Apr 8, 2026
…trollers (#7661)
* HBASE-29841: Split bulky ReadOnlyController into multiple smaller controllers
Currently we have created a single ReadOnlyController which needs to get added as coprocessor for master, region and region server. In this task we will be breaking ReadOnlyController into multiple smaller controller to avoid unnecessarily adding methods which are not relevant for particular role for example, master copocessor should only register methods which may run on master and not on region or region server.
* Addres review Comments
anmolnar pushed a commit that referenced this pull request Apr 10, 2026
…trollers (#7661)
* HBASE-29841: Split bulky ReadOnlyController into multiple smaller controllers
Currently we have created a single ReadOnlyController which needs to get added as coprocessor for master, region and region server. In this task we will be breaking ReadOnlyController into multiple smaller controller to avoid unnecessarily adding methods which are not relevant for particular role for example, master copocessor should only register methods which may run on master and not on region or region server.
* Addres review Comments
anmolnar pushed a commit that referenced this pull request May 5, 2026
…trollers (#7661)
* HBASE-29841: Split bulky ReadOnlyController into multiple smaller controllers
Currently we have created a single ReadOnlyController which needs to get added as coprocessor for master, region and region server. In this task we will be breaking ReadOnlyController into multiple smaller controller to avoid unnecessarily adding methods which are not relevant for particular role for example, master copocessor should only register methods which may run on master and not on region or region server.
* Addres review Comments
Sign up for freeto 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.

5 participants

@sharmaar12@Apache-HBase@anmolnar@wchevreuil@kgeisz