Skip to content

Commit

Permalink
Fix setting by time unit (#37192)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
jasontedor committed Jan 7, 2019
1 parent 1b83475 commit d290a0a
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1061,8 +1061,8 @@ public Builder put(String setting, double value) {
* @param value The time value
* @return The builder
*/
public Builder put(String setting, long value, TimeUnit timeUnit) {
put(setting, timeUnit.toMillis(value) + "ms");
public Builder put(final String setting, final long value, final TimeUnit timeUnit) {
put(setting, new TimeValue(value, timeUnit));
return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;
Expand Down Expand Up @@ -856,4 +857,18 @@ public void testFractionalByteSizeValue() {
assertThat(actual, equalTo(expected));
}

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

}
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ public void testRestoreWithDifferentMappingsAndSettings() throws Exception {

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

public void testEmptySnapshot() throws Exception {
Expand Down

0 comments on commit d290a0a

Please sign in to comment.