Download stalls when `max-workers==1`
Closed this issue ยท 3 comments
What happens?
A download during configuration time that's using download.run {}
stalls the configuration phase when max-workers==1
.
This is true for machines that only have one core, for containers with --cpus 1
(e.g. in Kubernetes clusters), or for people who prefer running Gradle with --max-workers=1
.
Why does it happen?
The issue occurs due to this call:
This call lets the current worker wait until another worker has processed the downloads that were enqueued in the worker thread. Since we only have one worker which is blocked by this call, no other worker will ever process the enqueued Jobs.
When running with max-workers==1
, Gradle will enter org.gradle.internal.resource.DefaultResourceLockCoordinationService#withStateLock
when enqueuing the download job. This will lead the current thread to stall in lock.wait()
The main thread will stall on the CompletableFuture
from above due to the get()
call in DownloadExtension#L29.
Now, if workerExecutor.await()
would be called, DefaultResourceLockCoordinationService#notifyStateChange
would be called which releases the lock on which the worker thread waits.
If this doesn't happen though, both threads are waiting for a lock that only the respective other thread could release. This leads to a lockup.
How to fix it?
When calling download
from configuration time, we need to always call workerExecutor.await()
, even on newer Gradle versions. This could be easily done by always forcing await when the DownloadExtension
is used.
I already have the code for this and will happily submit a PR!
How to reproduce?
Run gradlew --max-workers=1
with the following build.gradle
file:
plugins {
id "base"
id "de.undercouch.download" version "5.0.2"
}
download.run {
src 'https://example.com'
dest 'out.txt'
}
Thanks for spotting this and for providing such a thorough analysis. Very much appreciated! ๐
I've fixed the issue and released a new version 5.0.3.
I have to thank you for the quick fix and the immediate release :) This will help me a lot!
Oops. It seems I was too fast! I didn't let the unit tests run through. Please use 5.0.4 ๐