dependencies: Track downloading in a separate thread
This commit is contained in:
@@ -33,7 +33,6 @@ import org.jetbrains.kotlin.config.addKotlinSourceRoots
|
||||
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
||||
import org.jetbrains.kotlin.konan.target.TargetManager
|
||||
import org.jetbrains.kotlin.utils.KotlinPaths
|
||||
import java.io.File
|
||||
import kotlin.reflect.KFunction
|
||||
|
||||
class K2Native : CLICompiler<K2NativeCompilerArguments>() {
|
||||
|
||||
Vendored
-1
@@ -21,7 +21,6 @@ import groovy.transform.stc.FirstParam
|
||||
import groovy.transform.stc.FromString
|
||||
import org.jetbrains.kotlin.konan.target.*
|
||||
import org.jetbrains.kotlin.konan.util.DependencyProcessor
|
||||
|
||||
import static org.jetbrains.kotlin.konan.target.KonanTarget.*
|
||||
import org.jetbrains.kotlin.konan.properties.KonanProperties
|
||||
import org.jetbrains.kotlin.konan.properties.*
|
||||
|
||||
@@ -6,6 +6,10 @@ import java.net.URL
|
||||
import java.net.URLConnection
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.StandardCopyOption
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.concurrent.locks.ReentrantLock
|
||||
import kotlin.concurrent.thread
|
||||
import kotlin.concurrent.withLock
|
||||
|
||||
class DependencyDownloader(
|
||||
var maxAttempts: Int = DEFAULT_MAX_ATTEMPTS,
|
||||
@@ -21,29 +25,77 @@ class DependencyDownloader(
|
||||
RETURN_EXISTING
|
||||
}
|
||||
|
||||
class DownloadingProgress(@Volatile var currentBytes: Long, val totalBytes: Long) {
|
||||
@Volatile var done: Boolean = false
|
||||
private set
|
||||
@Volatile var exception: Throwable? = null
|
||||
private set
|
||||
|
||||
private val lock = ReentrantLock()
|
||||
private val condition = lock.newCondition()
|
||||
|
||||
val doneCorrectly: Boolean
|
||||
get() = done && exception != null
|
||||
|
||||
fun update(readBytes: Int) { currentBytes += readBytes }
|
||||
|
||||
fun done() = lock.withLock {
|
||||
done = true
|
||||
condition.signalAll()
|
||||
}
|
||||
|
||||
fun done(e: Throwable) = lock.withLock {
|
||||
done = true
|
||||
exception = e
|
||||
condition.signalAll()
|
||||
}
|
||||
|
||||
fun trackProgress(interval: Long,
|
||||
intervalTimeUnit: TimeUnit = TimeUnit.MILLISECONDS,
|
||||
action: (progress: DownloadingProgress) -> Unit) =
|
||||
lock.withLock {
|
||||
action(this)
|
||||
while (!done) {
|
||||
condition.await(interval, intervalTimeUnit)
|
||||
action(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun doDownload(originalUrl: URL,
|
||||
connection: URLConnection,
|
||||
tmpFile: File,
|
||||
currentBytes: Long,
|
||||
totalBytes: Long,
|
||||
append: Boolean) {
|
||||
@Suppress("NAME_SHADOWING")
|
||||
var currentBytes = currentBytes
|
||||
connection.getInputStream().use { from ->
|
||||
FileOutputStream(tmpFile, append).use { to ->
|
||||
val buffer = ByteArray(DEFAULT_BUFFER_SIZE)
|
||||
var read = from.read(buffer)
|
||||
while (read != -1) {
|
||||
to.write(buffer, 0, read)
|
||||
currentBytes += read
|
||||
updateProgressMsg(originalUrl.toString(), currentBytes, totalBytes)
|
||||
read = from.read(buffer)
|
||||
}
|
||||
if (currentBytes != totalBytes) {
|
||||
throw EOFException("The stream closed before end of downloading.")
|
||||
val progress = DownloadingProgress(currentBytes, totalBytes)
|
||||
|
||||
// TODO: Implement multi-thread downloading + use some sort of thread pool.
|
||||
thread {
|
||||
Thread.setDefaultUncaughtExceptionHandler { _, throwable -> progress.done(throwable) }
|
||||
connection.getInputStream().use { from ->
|
||||
FileOutputStream(tmpFile, append).use { to ->
|
||||
val buffer = ByteArray(DEFAULT_BUFFER_SIZE)
|
||||
var read = from.read(buffer)
|
||||
while (read != -1) {
|
||||
to.write(buffer, 0, read)
|
||||
progress.update(read)
|
||||
read = from.read(buffer)
|
||||
}
|
||||
if (currentBytes != totalBytes) {
|
||||
throw EOFException("The stream closed before end of downloading.")
|
||||
}
|
||||
progress.done()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
progress.trackProgress(1000) {
|
||||
updateProgressMsg(originalUrl.toString(), it.currentBytes, it.totalBytes)
|
||||
}
|
||||
if (!progress.doneCorrectly) {
|
||||
throw progress.exception!!
|
||||
}
|
||||
}
|
||||
|
||||
private fun tryHttpDownload(originalUrl: URL, connection: HttpURLConnection, tmpFile: File) {
|
||||
@@ -82,7 +134,7 @@ class DependencyDownloader(
|
||||
|
||||
/** Performs an attempt to download a specified file into the specified location */
|
||||
private fun tryDownload(url: URL, tmpFile: File) {
|
||||
var connection = url.openConnection()
|
||||
val connection = url.openConnection()
|
||||
if (connection is HttpURLConnection) {
|
||||
tryHttpDownload(url, connection, tmpFile)
|
||||
} else {
|
||||
@@ -152,8 +204,6 @@ class DependencyDownloader(
|
||||
print("\rDownloading dependency: $url (${currentBytes.humanReadable}/${totalBytes.humanReadable}). ")
|
||||
}
|
||||
|
||||
|
||||
|
||||
companion object {
|
||||
const val DEFAULT_MAX_ATTEMPTS = 10
|
||||
const val DEFAULT_ATTEMPT_INTERVAL_MS = 3000L
|
||||
|
||||
Reference in New Issue
Block a user