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 {
|
public class ActionThrottle {
|
||||||
private static Logger log = LoggerFactory.getLogger(ActionThrottle.class);
|
private static Logger log = LoggerFactory.getLogger(ActionThrottle.class);
|
||||||
|
|
||||||
private volatile long lastActionStartedAt;
|
private volatile Long lastActionStartedAt;
|
||||||
private volatile long minMsBetweenActions;
|
private volatile Long minMsBetweenActions;
|
||||||
|
|
||||||
private final String name;
|
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) {
|
public ActionThrottle(String name, long minMsBetweenActions) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.minMsBetweenActions = minMsBetweenActions;
|
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() {
|
public void markAttemptingAction() {
|
||||||
lastActionStartedAt = System.nanoTime();
|
lastActionStartedAt = nanoTimeSource.getTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void minimumWaitBetweenActions() {
|
public void minimumWaitBetweenActions() {
|
||||||
if (lastActionStartedAt == 0) {
|
if (lastActionStartedAt == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
long diff = System.nanoTime() - lastActionStartedAt;
|
long diff = nanoTimeSource.getTime() - lastActionStartedAt;
|
||||||
int diffMs = (int) TimeUnit.MILLISECONDS.convert(diff, TimeUnit.NANOSECONDS);
|
int diffMs = (int) TimeUnit.MILLISECONDS.convert(diff, TimeUnit.NANOSECONDS);
|
||||||
long minNsBetweenActions = TimeUnit.NANOSECONDS.convert(minMsBetweenActions, TimeUnit.MILLISECONDS);
|
long minNsBetweenActions = TimeUnit.NANOSECONDS.convert(minMsBetweenActions, TimeUnit.MILLISECONDS);
|
||||||
log.info("The last {} attempt started {}ms ago.", name, diffMs);
|
log.info("The last {} attempt started {}ms ago.", name, diffMs);
|
||||||
|
@ -53,7 +73,7 @@ public class ActionThrottle {
|
||||||
if (diffMs > 0 && diff < minNsBetweenActions) {
|
if (diffMs > 0 && diff < minNsBetweenActions) {
|
||||||
sleep = (int) TimeUnit.MILLISECONDS.convert(minNsBetweenActions - diff, TimeUnit.NANOSECONDS);
|
sleep = (int) TimeUnit.MILLISECONDS.convert(minNsBetweenActions - diff, TimeUnit.NANOSECONDS);
|
||||||
} else if (diffMs == 0) {
|
} else if (diffMs == 0) {
|
||||||
sleep = (int) minMsBetweenActions;
|
sleep = minMsBetweenActions.intValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sleep > 0) {
|
if (sleep > 0) {
|
||||||
|
|
|
@ -17,9 +17,12 @@ package org.apache.solr.cloud;
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.apache.solr.SolrTestCaseJ4;
|
import org.apache.solr.SolrTestCaseJ4;
|
||||||
|
import org.apache.solr.cloud.ActionThrottle.NanoTimeSource;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -27,6 +30,21 @@ import org.slf4j.LoggerFactory;
|
||||||
public class ActionThrottleTest extends SolrTestCaseJ4 {
|
public class ActionThrottleTest extends SolrTestCaseJ4 {
|
||||||
protected static Logger log = LoggerFactory.getLogger(ActionThrottleTest.class);
|
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
|
@Test
|
||||||
public void testBasics() throws Exception {
|
public void testBasics() throws Exception {
|
||||||
|
@ -60,4 +78,20 @@ public class ActionThrottleTest extends SolrTestCaseJ4 {
|
||||||
assertTrue(elaspsedTime + "ms", elaspsedTime >= 995);
|
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