Skip to content

Commit 3b48b99

Browse files
authored
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 382e4d3 commit 3b48b99

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,8 +1019,8 @@ public Builder put(String setting, double value) {
10191019
* @param value The time value
10201020
* @return The builder
10211021
*/
1022-
public Builder put(String setting, long value, TimeUnit timeUnit) {
1023-
put(setting, timeUnit.toMillis(value) + "ms");
1022+
public Builder put(final String setting, final long value, final TimeUnit timeUnit) {
1023+
put(setting, new TimeValue(value, timeUnit));
10241024
return this;
10251025
}
10261026

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import java.util.Map;
4848
import java.util.NoSuchElementException;
4949
import java.util.Set;
50+
import java.util.concurrent.TimeUnit;
5051

5152
import static org.hamcrest.Matchers.contains;
5253
import static org.hamcrest.Matchers.containsInAnyOrder;
@@ -744,4 +745,18 @@ public void testFractionalByteSizeValue() {
744745
assertThat(actual, equalTo(expected));
745746
}
746747

748+
public void testSetByTimeUnit() {
749+
final Setting<TimeValue> setting =
750+
Setting.timeSetting("key", TimeValue.parseTimeValue(randomTimeValue(0, 24, "h"), "key"), TimeValue.ZERO);
751+
final TimeValue expected = new TimeValue(1500, TimeUnit.MICROSECONDS);
752+
final Settings settings = Settings.builder().put("key", expected.getMicros(), TimeUnit.MICROSECONDS).build();
753+
/*
754+
* Previously we would internally convert the duration to a string by converting to milliseconds which could lose precision (e.g.,
755+
* 1500 microseconds would be converted to 1ms). Effectively this test is then asserting that we no longer make this mistake when
756+
* doing the internal string conversion. Instead, we convert to a duration using a method that does not lose the original unit.
757+
*/
758+
final TimeValue actual = setting.get(settings);
759+
assertThat(actual, equalTo(expected));
760+
}
761+
747762
}

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

Lines changed: 1 addition & 1 deletion
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)