Skip to content

Commit

Permalink
loadbalancer: fix NormalizedTimeSourceExecutor to work with units oth…
Browse files Browse the repository at this point in the history
…er than nanos (#2791)

Motivation:

The time source normalizes itself using nanoseconds regardless
of what units the user is requesting.

Modifications:

- Always get the current time in nanos, normalize, then convert
  to the desired units.

Result:

Better behavior.
  • Loading branch information
bryce-anderson authored Dec 21, 2023
1 parent aeca73c commit e5784f8
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,16 @@
*/
final class NormalizedTimeSourceExecutor extends DelegatingExecutor {

private final long offset;
private final long offsetNanos;

NormalizedTimeSourceExecutor(final Executor delegate) {
super(delegate);
offset = delegate.currentTime(NANOSECONDS);
offsetNanos = delegate.currentTime(NANOSECONDS);
}

@Override
public long currentTime(final TimeUnit unit) {
return delegate().currentTime(unit) - offset;
final long elapsedNanos = delegate().currentTime(NANOSECONDS) - offsetNanos;
return unit.convert(elapsedNanos, NANOSECONDS);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@

import static java.lang.Long.MAX_VALUE;
import static java.lang.Long.MIN_VALUE;
import static java.util.concurrent.TimeUnit.MICROSECONDS;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;

Expand Down Expand Up @@ -60,4 +63,15 @@ void minValue(long initialValue) {
advanceAndVerify(10, MAX_VALUE + 10);
advanceAndVerify(MAX_VALUE - 8, 0);
}

@ParameterizedTest(name = "{displayName} [{index}]: initialValue={0}")
@ValueSource(longs = {MIN_VALUE, -100, 0, 100, MAX_VALUE})
void otherUnits(long initialValue) {
setUp(initialValue);
testExecutor.advanceTimeByNoExecuteTasks(1, SECONDS);
assertThat(executor.currentTime(SECONDS), is(1L));
assertThat(executor.currentTime(MILLISECONDS), is(1_000L));
assertThat(executor.currentTime(MICROSECONDS), is(1_000_000L));
assertThat(executor.currentTime(NANOSECONDS), is(1_000_000_000L));
}
}

0 comments on commit e5784f8

Please sign in to comment.