BATCH-1409: By using a special queue we can force the repeat template to block only on calling thread, not on workers.

This commit is contained in:
dsyer
2009-09-24 06:14:06 +00:00
parent 685065a476
commit ab5ece862a
4 changed files with 264 additions and 169 deletions

View File

@@ -0,0 +1,66 @@
package org.springframework.batch.repeat.support;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.springframework.batch.repeat.RepeatContext;
import org.springframework.batch.repeat.RepeatStatus;
public class ResultHolderResultQueueTests {
private ResultHolderResultQueue queue = new ResultHolderResultQueue(10);
@Test
public void testPutTake() throws Exception {
queue.expect();
assertTrue(queue.isExpecting());
assertTrue(queue.isEmpty());
queue.put(new TestResultHolder(RepeatStatus.CONTINUABLE));
assertFalse(queue.isEmpty());
assertTrue(queue.take().getResult().isContinuable());
assertFalse(queue.isExpecting());
}
@Test
public void testOrdering() throws Exception {
queue.expect();
queue.expect();
queue.put(new TestResultHolder(RepeatStatus.FINISHED));
queue.put(new TestResultHolder(RepeatStatus.CONTINUABLE));
assertFalse(queue.isEmpty());
assertTrue(queue.take().getResult().isContinuable());
assertFalse(queue.take().getResult().isContinuable());
}
private static class TestResultHolder implements ResultHolder {
private RepeatStatus result;
private Throwable error;
public TestResultHolder(RepeatStatus result) {
super();
this.result = result;
}
public TestResultHolder(Throwable error) {
super();
this.error = error;
}
public RepeatContext getContext() {
return null;
}
public Throwable getError() {
return error;
}
public RepeatStatus getResult() {
return result;
}
}
}

View File

@@ -47,7 +47,7 @@ public class TaskExecutorRepeatTemplateBulkAsynchronousTests {
static Log logger = LogFactory.getLog(TaskExecutorRepeatTemplateBulkAsynchronousTests.class);
private static int TOTAL = 100;
private int total = 100;
private int throttleLimit = 30;
@@ -76,7 +76,7 @@ public class TaskExecutorRepeatTemplateBulkAsynchronousTests {
public RepeatStatus doInIteration(RepeatContext context) throws Exception {
int position = count.incrementAndGet();
String item = position <= TOTAL ? "" + position : null;
String item = position <= total ? "" + position : null;
items.add("" + item);
if (item != null) {
beBusy();
@@ -105,7 +105,7 @@ public class TaskExecutorRepeatTemplateBulkAsynchronousTests {
int frequency = Collections.frequency(items, "null");
// System.err.println(items);
// System.err.println("Frequency: " + frequency);
assertEquals(TOTAL, items.size() - frequency);
assertEquals(total, items.size() - frequency);
assertTrue(frequency > 1);
assertTrue(frequency <= throttleLimit + 1);
@@ -120,7 +120,7 @@ public class TaskExecutorRepeatTemplateBulkAsynchronousTests {
int frequency = Collections.frequency(items, "null");
// System.err.println("Frequency: " + frequency);
// System.err.println("Items: " + items);
assertEquals(TOTAL, items.size() - frequency);
assertEquals(total, items.size() - frequency);
assertTrue(frequency > 1);
assertTrue(frequency <= throttleLimit + 1);
@@ -131,7 +131,8 @@ public class TaskExecutorRepeatTemplateBulkAsynchronousTests {
early = 2;
SimpleAsyncTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor();
// Set the concurrency limit below the throttle limit for possible starvation condition
// Set the concurrency limit below the throttle limit for possible
// starvation condition
taskExecutor.setConcurrencyLimit(20);
template.setTaskExecutor(taskExecutor);
@@ -140,7 +141,7 @@ public class TaskExecutorRepeatTemplateBulkAsynchronousTests {
// System.err.println("Frequency: " + frequency);
// System.err.println("Items: " + items);
// Extra tasks will be submitted before the termination is detected
assertEquals(TOTAL, items.size() - frequency);
assertEquals(total, items.size() - frequency);
assertTrue(frequency <= throttleLimit + 1);
}
@@ -148,18 +149,23 @@ public class TaskExecutorRepeatTemplateBulkAsynchronousTests {
@Test
public void testThrottleLimitEarlyFinishOneThread() throws Exception {
early = 2;
early = 4;
SimpleAsyncTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor();
taskExecutor.setConcurrencyLimit(1);
// This is kind of slow with only one thread, so reduce size:
throttleLimit = 10;
total = 20;
template.setThrottleLimit(throttleLimit);
template.setTaskExecutor(taskExecutor);
template.iterate(callback);
int frequency = Collections.frequency(items, "null");
// System.err.println("Frequency: " + frequency);
// System.err.println("Items: " + items);
// One extra task will be submitted before the termination is detected
assertEquals(early + 1, items.size() - frequency);
assertEquals(0, frequency);
assertEquals(total, items.size() - frequency);
assertTrue(frequency <= throttleLimit + 1);
}