-
Notifications
You must be signed in to change notification settings - Fork 0
Rate limit write load decider logging #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,8 +18,10 @@ | |
| import org.elasticsearch.cluster.routing.ShardRouting; | ||
| import org.elasticsearch.cluster.routing.allocation.RoutingAllocation; | ||
| import org.elasticsearch.cluster.routing.allocation.WriteLoadConstraintSettings; | ||
| import org.elasticsearch.common.FrequencyCappedAction; | ||
| import org.elasticsearch.common.settings.ClusterSettings; | ||
| import org.elasticsearch.core.Strings; | ||
| import org.elasticsearch.core.TimeValue; | ||
| import org.elasticsearch.threadpool.ThreadPool; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ThreadPool Injection OpportunityThreadPool is imported but not used in constructor while System::currentTimeMillis is used directly. ThreadPool.relativeTimeInMillis() would provide consistent time source and better testability. Standards
|
||
|
|
||
| /** | ||
|
|
@@ -31,10 +33,16 @@ public class WriteLoadConstraintDecider extends AllocationDecider { | |
|
|
||
| public static final String NAME = "write_load"; | ||
|
|
||
| private final FrequencyCappedAction logInterventionMessage; | ||
| private final WriteLoadConstraintSettings writeLoadConstraintSettings; | ||
|
|
||
| public WriteLoadConstraintDecider(ClusterSettings clusterSettings) { | ||
| this.writeLoadConstraintSettings = new WriteLoadConstraintSettings(clusterSettings); | ||
| logInterventionMessage = new FrequencyCappedAction(System::currentTimeMillis, TimeValue.ZERO); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. System Clock DependencySystem::currentTimeMillis creates direct dependency on system clock which can cause issues during clock adjustments or in testing environments. Clock changes can break rate limiting behavior and make testing non-deterministic. Standards
|
||
| clusterSettings.initializeAndWatch( | ||
| WriteLoadConstraintSettings.WRITE_LOAD_DECIDER_MINIMUM_LOGGING_INTERVAL, | ||
| logInterventionMessage::setMinInterval | ||
| ); | ||
| } | ||
|
|
||
| @Override | ||
|
|
@@ -77,7 +85,9 @@ public Decision canAllocate(ShardRouting shardRouting, RoutingNode node, Routing | |
| nodeWriteThreadPoolLoadThreshold, | ||
| shardRouting.shardId() | ||
| ); | ||
| logger.debug(explain); | ||
| if (logger.isDebugEnabled()) { | ||
| logInterventionMessage.maybeExecute(() -> logger.debug(explain)); | ||
| } | ||
|
Comment on lines
+88
to
+90
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This rate-limited logging logic is duplicated in three places within this class (here, lines 110-112, and 160-162). To improve maintainability and reduce code duplication, consider extracting this logic into a private helper method. For example, you could add: private void maybeLogIntervention(String explanation) {
if (logger.isDebugEnabled()) {
logInterventionMessage.maybeExecute(() -> logger.debug(explanation));
}
}And then replace the duplicated blocks with a call to |
||
| return Decision.single(Decision.Type.NOT_PREFERRED, NAME, explain); | ||
| } | ||
|
|
||
|
|
@@ -97,7 +107,9 @@ public Decision canAllocate(ShardRouting shardRouting, RoutingNode node, Routing | |
| shardWriteLoad, | ||
| nodeWriteThreadPoolStats.totalThreadPoolThreads() | ||
| ); | ||
| logger.debug(explain); | ||
| if (logger.isDebugEnabled()) { | ||
| logInterventionMessage.maybeExecute(() -> logger.debug(explain)); | ||
| } | ||
| return Decision.single(Decision.Type.NOT_PREFERRED, NAME, explain); | ||
| } | ||
|
|
||
|
|
@@ -108,7 +120,6 @@ public Decision canAllocate(ShardRouting shardRouting, RoutingNode node, Routing | |
| node.nodeId(), | ||
| newWriteThreadPoolUtilization | ||
| ); | ||
| logger.trace(explanation); | ||
| return allocation.decision(Decision.YES, NAME, explanation); | ||
| } | ||
|
|
||
|
|
@@ -146,7 +157,9 @@ public Decision canRemain(IndexMetadata indexMetadata, ShardRouting shardRouting | |
| nodeWriteThreadPoolQueueLatencyThreshold.toHumanReadableString(2), | ||
| nodeWriteThreadPoolStats.averageThreadPoolUtilization() | ||
| ); | ||
| logger.debug(explain); | ||
| if (logger.isDebugEnabled()) { | ||
| logInterventionMessage.maybeExecute(() -> logger.debug(explain)); | ||
| } | ||
| return Decision.single(Decision.Type.NOT_PREFERRED, NAME, explain); | ||
| } | ||
|
|
||
|
|
@@ -156,7 +169,6 @@ public Decision canRemain(IndexMetadata indexMetadata, ShardRouting shardRouting | |
| nodeWriteThreadPoolStats.maxThreadPoolQueueLatencyMillis(), | ||
| nodeWriteThreadPoolQueueLatencyThreshold.toHumanReadableString(2) | ||
| ); | ||
| logger.trace(explanation); | ||
| return allocation.decision(Decision.YES, NAME, explanation); | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: Ensure the class API surface includes access to the new setting by exposing
getMinimumLoggingInterval()and make the stored value updateable by adding an initializeAndWatch call in the constructor to updateminimumLoggingInterval. [maintainability]