-
Notifications
You must be signed in to change notification settings - Fork 470
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix usages of some async utilities #1610
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -70,33 +70,57 @@ public void run() { | |
long timeoutAt = 0; | ||
int unsuccessfulInterruptAttempts = 0; | ||
|
||
syncWithThread(startLatch, "feature", methodName); | ||
boolean syncedWithFeature = false; | ||
try { | ||
startLatch.countDown(); | ||
syncedWithFeature = startLatch.await(5, TimeUnit.SECONDS); | ||
} catch (InterruptedException ignored) { | ||
// this is our own thread, so we can ignore the interruption safely | ||
} | ||
if (!syncedWithFeature) { | ||
System.out.printf("[spock.lang.Timeout] Could not sync with Feature for method '%s'", methodName); | ||
} | ||
|
||
while (waitMillis > 0) { | ||
long waitStart = System.nanoTime(); | ||
try { | ||
synced = sync.offer(stackTrace, waitMillis, TimeUnit.MILLISECONDS); | ||
} catch (InterruptedException ignored) { | ||
// this is our own thread, so we can ignore the interruption safely and continue the remaining waiting | ||
waitMillis -= TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - waitStart); | ||
continue; | ||
} | ||
break; | ||
} | ||
Comment on lines
+84
to
+94
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this necessary? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If it indeed happens that the watcher thread is interrupted during the initial wait, it should continue the initial wait, shouldn't it? |
||
if (!synced) { | ||
stackTrace = mainThread.getStackTrace(); | ||
waitMillis = 250; | ||
} | ||
while (!synced) { | ||
mainThread.interrupt(); | ||
try { | ||
synced = sync.offer(stackTrace, waitMillis, TimeUnit.MILLISECONDS); | ||
} catch (InterruptedException ignored) { | ||
// The mission of this thread is to repeatedly interrupt the main thread until | ||
// the latter returns. Once this mission has been accomplished, this thread will die quickly | ||
} | ||
if (!synced) { | ||
long now = System.nanoTime(); | ||
if (stackTrace.length == 0) { | ||
logMethodTimeout(methodName, timeoutSeconds); | ||
stackTrace = mainThread.getStackTrace(); | ||
waitMillis = 250; | ||
timeoutAt = now; | ||
} else { | ||
waitMillis *= 2; | ||
logUnsuccessfulInterrupt(methodName, now, timeoutAt, waitMillis, ++unsuccessfulInterruptAttempts); | ||
} | ||
mainThread.interrupt(); | ||
System.out.printf("[spock.lang.Timeout] Method '%s' has not yet returned - interrupting. Next try in %1.2f seconds.\n", | ||
methodName, waitMillis / 1000.); | ||
} | ||
} | ||
} | ||
}.start(); | ||
|
||
syncWithThread(startLatch, "watcher", methodName); | ||
boolean syncedWithWatcher = false; | ||
try { | ||
startLatch.countDown(); | ||
syncedWithWatcher = startLatch.await(5, TimeUnit.SECONDS); | ||
} finally { | ||
if (!syncedWithWatcher) { | ||
System.out.printf("[spock.lang.Timeout] Could not sync with Watcher for method '%s'", invocation.getMethod().getName()); | ||
} | ||
} | ||
|
||
Throwable saved = null; | ||
try { | ||
|
@@ -216,13 +240,4 @@ private static Pair<Integer, Integer> findThreadSection(List<String> lines, Stri | |
|
||
return null; | ||
} | ||
|
||
private static void syncWithThread(CountDownLatch startLatch, String threadName, String methodName) { | ||
try { | ||
startLatch.countDown(); | ||
startLatch.await(5, TimeUnit.SECONDS); | ||
} catch (InterruptedException ignored) { | ||
System.out.printf("[spock.lang.Timeout] Could not sync with %s thread for method '%s'", threadName, methodName); | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using
join
to make it un-interruptible?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does not get uninterruptible.
It just does not throw checked exceptions but unchecked ones.
If you use
get()
you might getInterruptedException
and then have to handle it properly.Just ignoring is not ok at that spot as this is not a self-managed thread, so in most cases you should either rethrow or at least re-interrupt so that code higher in the stack can properly handle the interrupt and so on.
And by using
join()
here you can simply get around all that, as you don't mess with the interrupted exception yourself.And
ExecutionException
would never come here anyway, as the future is never completed exceptionally.