Skip to content

Commit cb5d010

Browse files
committed
Fix setting by time unit (#37192)
This commit fixes an issue with a settings builder method that allows setting a duration by time unit. In particular, this method can suffer from a loss of precision. For example, if the input duration is 1500 microseconds then internally we are converting this to "1ms", demonstrating the loss of precision. Instead, we should internally convert this to a TimeValue that correctly represents the input duration, and then convert this to a string using a method that does not lose the unit. That is what this commit does.
1 parent 5f3dfec commit cb5d010

File tree

3 files changed

+18
-3
lines changed

3 files changed

+18
-3
lines changed

server/src/main/java/org/elasticsearch/common/settings/Settings.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1061,8 +1061,8 @@ public Builder put(String setting, double value) {
10611061
* @param value The time value
10621062
* @return The builder
10631063
*/
1064-
public Builder put(String setting, long value, TimeUnit timeUnit) {
1065-
put(setting, timeUnit.toMillis(value) + "ms");
1064+
public Builder put(final String setting, final long value, final TimeUnit timeUnit) {
1065+
put(setting, new TimeValue(value, timeUnit));
10661066
return this;
10671067
}
10681068

server/src/test/java/org/elasticsearch/common/settings/SettingsTests.java

+15
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
import java.util.Map;
5555
import java.util.NoSuchElementException;
5656
import java.util.Set;
57+
import java.util.concurrent.TimeUnit;
5758

5859
import static org.hamcrest.Matchers.contains;
5960
import static org.hamcrest.Matchers.containsInAnyOrder;
@@ -856,4 +857,18 @@ public void testFractionalByteSizeValue() {
856857
assertThat(actual, equalTo(expected));
857858
}
858859

860+
public void testSetByTimeUnit() {
861+
final Setting<TimeValue> setting =
862+
Setting.timeSetting("key", TimeValue.parseTimeValue(randomTimeValue(0, 24, "h"), "key"), TimeValue.ZERO);
863+
final TimeValue expected = new TimeValue(1500, TimeUnit.MICROSECONDS);
864+
final Settings settings = Settings.builder().put("key", expected.getMicros(), TimeUnit.MICROSECONDS).build();
865+
/*
866+
* Previously we would internally convert the duration to a string by converting to milliseconds which could lose precision (e.g.,
867+
* 1500 microseconds would be converted to 1ms). Effectively this test is then asserting that we no longer make this mistake when
868+
* doing the internal string conversion. Instead, we convert to a duration using a method that does not lose the original unit.
869+
*/
870+
final TimeValue actual = setting.get(settings);
871+
assertThat(actual, equalTo(expected));
872+
}
873+
859874
}

server/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,7 @@ public void testRestoreWithDifferentMappingsAndSettings() throws Exception {
445445

446446
logger.info("--> assert that old settings are restored");
447447
GetSettingsResponse getSettingsResponse = client.admin().indices().prepareGetSettings("test-idx").execute().actionGet();
448-
assertThat(getSettingsResponse.getSetting("test-idx", "index.refresh_interval"), equalTo("10000ms"));
448+
assertThat(getSettingsResponse.getSetting("test-idx", "index.refresh_interval"), equalTo("10s"));
449449
}
450450

451451
public void testEmptySnapshot() throws Exception {

0 commit comments

Comments
 (0)