mirror of https://github.com/apache/lucene.git
SOLR-7285: ActionThrottle will not pause if getNanoTime first returns 0.
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1668370 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
0a8dfe05dc
commit
8e6f93c6ff
|
@ -26,25 +26,45 @@ import org.slf4j.LoggerFactory;
|
|||
public class ActionThrottle {
|
||||
private static Logger log = LoggerFactory.getLogger(ActionThrottle.class);
|
||||
|
||||
private volatile long lastActionStartedAt;
|
||||
private volatile long minMsBetweenActions;
|
||||
private volatile Long lastActionStartedAt;
|
||||
private volatile Long minMsBetweenActions;
|
||||
|
||||
private final String name;
|
||||
|
||||
private final NanoTimeSource nanoTimeSource;
|
||||
|
||||
public interface NanoTimeSource {
|
||||
long getTime();
|
||||
}
|
||||
|
||||
private static class DefaultNanoTimeSource implements NanoTimeSource {
|
||||
@Override
|
||||
public long getTime() {
|
||||
return System.nanoTime();
|
||||
}
|
||||
}
|
||||
|
||||
public ActionThrottle(String name, long minMsBetweenActions) {
|
||||
this.name = name;
|
||||
this.minMsBetweenActions = minMsBetweenActions;
|
||||
this.nanoTimeSource = new DefaultNanoTimeSource();
|
||||
}
|
||||
|
||||
public ActionThrottle(String name, long minMsBetweenActions, NanoTimeSource nanoTimeSource) {
|
||||
this.name = name;
|
||||
this.minMsBetweenActions = minMsBetweenActions;
|
||||
this.nanoTimeSource = nanoTimeSource;
|
||||
}
|
||||
|
||||
public void markAttemptingAction() {
|
||||
lastActionStartedAt = System.nanoTime();
|
||||
lastActionStartedAt = nanoTimeSource.getTime();
|
||||
}
|
||||
|
||||
public void minimumWaitBetweenActions() {
|
||||
if (lastActionStartedAt == 0) {
|
||||
if (lastActionStartedAt == null) {
|
||||
return;
|
||||
}
|
||||
long diff = System.nanoTime() - lastActionStartedAt;
|
||||
long diff = nanoTimeSource.getTime() - lastActionStartedAt;
|
||||
int diffMs = (int) TimeUnit.MILLISECONDS.convert(diff, TimeUnit.NANOSECONDS);
|
||||
long minNsBetweenActions = TimeUnit.NANOSECONDS.convert(minMsBetweenActions, TimeUnit.MILLISECONDS);
|
||||
log.info("The last {} attempt started {}ms ago.", name, diffMs);
|
||||
|
@ -53,7 +73,7 @@ public class ActionThrottle {
|
|||
if (diffMs > 0 && diff < minNsBetweenActions) {
|
||||
sleep = (int) TimeUnit.MILLISECONDS.convert(minNsBetweenActions - diff, TimeUnit.NANOSECONDS);
|
||||
} else if (diffMs == 0) {
|
||||
sleep = (int) minMsBetweenActions;
|
||||
sleep = minMsBetweenActions.intValue();
|
||||
}
|
||||
|
||||
if (sleep > 0) {
|
||||
|
|
|
@ -17,9 +17,12 @@ package org.apache.solr.cloud;
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.solr.SolrTestCaseJ4;
|
||||
import org.apache.solr.cloud.ActionThrottle.NanoTimeSource;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -27,6 +30,21 @@ import org.slf4j.LoggerFactory;
|
|||
public class ActionThrottleTest extends SolrTestCaseJ4 {
|
||||
protected static Logger log = LoggerFactory.getLogger(ActionThrottleTest.class);
|
||||
|
||||
static class TestNanoTimeSource implements NanoTimeSource {
|
||||
|
||||
private List<Long> returnValues;
|
||||
private int index = 0;
|
||||
|
||||
public TestNanoTimeSource(List<Long> returnValues) {
|
||||
this.returnValues = returnValues;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTime() {
|
||||
return returnValues.get(index++);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBasics() throws Exception {
|
||||
|
@ -59,5 +77,21 @@ public class ActionThrottleTest extends SolrTestCaseJ4 {
|
|||
|
||||
assertTrue(elaspsedTime + "ms", elaspsedTime >= 995);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAZeroNanoTimeReturnInWait() throws Exception {
|
||||
|
||||
ActionThrottle at = new ActionThrottle("test", 1000, new TestNanoTimeSource(Arrays.asList(new Long[]{0L, 10L})));
|
||||
long start = System.nanoTime();
|
||||
|
||||
at.markAttemptingAction();
|
||||
|
||||
at.minimumWaitBetweenActions();
|
||||
|
||||
long elaspsedTime = TimeUnit.MILLISECONDS.convert(System.nanoTime() - start, TimeUnit.NANOSECONDS);
|
||||
|
||||
assertTrue(elaspsedTime + "ms", elaspsedTime >= 995);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue