Skip to content

Commit 212fc78

Browse files
committed
Fix usages of some async utilities
1 parent 4c82f75 commit 212fc78

File tree

5 files changed

+41
-30
lines changed

5 files changed

+41
-30
lines changed

spock-core/src/main/java/org/spockframework/runtime/extension/builtin/RepeatUntilFailureExtension.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,8 @@ public void runIterations(IDataIterator dataIterator, IIterationRunner iteration
3737
dataIterator.forEachRemaining(data::add);
3838
for (int attempt = 0; attempt < maxAttempts; attempt++) {
3939
for (Object[] args : data) {
40-
try {
41-
ExecutionResult executionResult = iterationRunner.runIteration(args, maxIterations).get();
42-
if (executionResult == ExecutionResult.FAILED) {
43-
return;
44-
}
45-
} catch (InterruptedException | ExecutionException e) {
40+
ExecutionResult executionResult = iterationRunner.runIteration(args, maxIterations).join();
41+
if (executionResult == ExecutionResult.FAILED) {
4642
return;
4743
}
4844
}

spock-core/src/main/java/org/spockframework/runtime/extension/builtin/TimeoutInterceptor.java

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -51,41 +51,57 @@ public void run() {
5151
long waitMillis = timeout.unit().toMillis(timeout.value());
5252
boolean synced = false;
5353

54+
boolean syncedWithFeature = false;
5455
try {
5556
startLatch.countDown();
56-
startLatch.await(5, TimeUnit.SECONDS);
57+
syncedWithFeature = startLatch.await(5, TimeUnit.SECONDS);
5758
} catch (InterruptedException ignored) {
59+
// this is our own thread, so we can ignore the interruption safely
60+
}
61+
if (!syncedWithFeature) {
5862
System.out.printf("[spock.lang.Timeout] Could not sync with Feature for method '%s'", invocation.getMethod().getName());
5963
}
6064

65+
while (waitMillis > 0) {
66+
long waitStart = System.nanoTime();
67+
try {
68+
synced = sync.offer(stackTrace, waitMillis, TimeUnit.MILLISECONDS);
69+
} catch (InterruptedException ignored) {
70+
// this is our own thread, so we can ignore the interruption safely and continue the remaining waiting
71+
waitMillis -= TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - waitStart);
72+
continue;
73+
}
74+
break;
75+
}
76+
if (!synced) {
77+
stackTrace = mainThread.getStackTrace();
78+
waitMillis = 250;
79+
}
6180
while (!synced) {
81+
mainThread.interrupt();
6282
try {
6383
synced = sync.offer(stackTrace, waitMillis, TimeUnit.MILLISECONDS);
6484
} catch (InterruptedException ignored) {
6585
// The mission of this thread is to repeatedly interrupt the main thread until
6686
// the latter returns. Once this mission has been accomplished, this thread will die quickly
6787
}
6888
if (!synced) {
69-
if (stackTrace.length == 0) {
70-
stackTrace = mainThread.getStackTrace();
71-
waitMillis = 250;
72-
} else {
73-
waitMillis *= 2;
74-
System.out.printf("[spock.lang.Timeout] Method '%s' has not yet returned - interrupting. Next try in %1.2f seconds.\n",
75-
invocation.getMethod().getName(), waitMillis / 1000.);
76-
}
77-
mainThread.interrupt();
89+
waitMillis *= 2;
90+
System.out.printf("[spock.lang.Timeout] Method '%s' has not yet returned - interrupting. Next try in %1.2f seconds.\n",
91+
invocation.getMethod().getName(), waitMillis / 1000.);
7892
}
7993
}
8094
}
8195
}.start();
8296

83-
97+
boolean syncedWithWatcher = false;
8498
try {
8599
startLatch.countDown();
86-
startLatch.await(5, TimeUnit.SECONDS);
87-
} catch (InterruptedException ignored) {
88-
System.out.printf("[spock.lang.Timeout] Could not sync with Watcher for method '%s'", invocation.getMethod().getName());
100+
syncedWithWatcher = startLatch.await(5, TimeUnit.SECONDS);
101+
} finally {
102+
if (!syncedWithWatcher) {
103+
System.out.printf("[spock.lang.Timeout] Could not sync with Watcher for method '%s'", invocation.getMethod().getName());
104+
}
89105
}
90106

91107
Throwable saved = null;

spock-core/src/main/java/spock/util/concurrent/AsyncConditions.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,15 +131,14 @@ public void await() throws Throwable {
131131
* @throws Throwable the first exception thrown by an evaluate block
132132
*/
133133
public void await(double seconds) throws Throwable {
134-
latch.await((long) (seconds * 1000), TimeUnit.MILLISECONDS);
134+
boolean evalBlocksFinished = latch.await((long) (seconds * 1000), TimeUnit.MILLISECONDS);
135135
if (!exceptions.isEmpty())
136136
throw exceptions.poll();
137137

138-
long pendingEvalBlocks = latch.getCount();
139-
if (pendingEvalBlocks > 0) {
138+
if (!evalBlocksFinished) {
140139
String msg = String.format("Async conditions timed out " +
141140
"after %1.2f seconds; %d out of %d evaluate blocks did not complete in time",
142-
seconds, pendingEvalBlocks, numEvalBlocks);
141+
seconds, latch.getCount(), numEvalBlocks);
143142
throw new SpockTimeoutError(seconds, msg);
144143
}
145144
}

spock-specs/src/test/groovy/org/spockframework/smoke/extension/ParallelSpec.groovy

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ class ParallelSpec extends EmbeddedSpecification {
265265
@ResourceLock(value = "a", mode = ResourceAccessMode.READ)
266266
def writeA() {
267267
when:
268-
incrementAndBlock(atomicInteger, latch)
268+
incrementAndBlock(atomicInteger, latch, 10000)
269269
270270
then:
271271
atomicInteger.get() == 3
@@ -519,15 +519,15 @@ class ParallelSpec extends EmbeddedSpecification {
519519
throws InterruptedException {
520520
int value = sharedResource.incrementAndGet()
521521
countDownLatch.countDown()
522-
countDownLatch.await(timeout, MILLISECONDS)
522+
assert countDownLatch.await(timeout, MILLISECONDS) : 'Timeout expired'
523523
return value
524524
}
525525

526526
static void storeAndBlockAndCheck(AtomicInteger sharedResource, CountDownLatch countDownLatch, long timeout = 100)
527527
throws InterruptedException {
528528
int value = sharedResource.get()
529529
countDownLatch.countDown()
530-
countDownLatch.await(timeout, MILLISECONDS)
530+
assert countDownLatch.await(timeout, MILLISECONDS) : 'Timeout expired'
531531
assert value == sharedResource.get()
532532
}
533533
}

spock-specs/src/test/groovy/org/spockframework/smoke/mock/InvokingMocksFromMultipleThreads.groovy

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class InvokingMocksFromMultipleThreads extends Specification {
4242
}
4343
}
4444
}
45-
latch.await(10, TimeUnit.SECONDS)
45+
assert latch.await(10, TimeUnit.SECONDS) : 'Timeout expired'
4646

4747
then:
4848
interaction {
@@ -68,7 +68,7 @@ class InvokingMocksFromMultipleThreads extends Specification {
6868
}
6969
}
7070
}
71-
latch.await(10, TimeUnit.SECONDS)
71+
assert latch.await(10, TimeUnit.SECONDS) : 'Timeout expired'
7272

7373
then:
7474
interaction {
@@ -93,7 +93,7 @@ class InvokingMocksFromMultipleThreads extends Specification {
9393
}
9494
}
9595
}
96-
latch.await(10, TimeUnit.SECONDS)
96+
assert latch.await(10, TimeUnit.SECONDS) : 'Timeout expired'
9797

9898
then:
9999
interaction {

0 commit comments

Comments
 (0)