[SQUASHME] Review fixes
This commit is contained in:
+2
-2
@@ -15,8 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
//
|
//
|
||||||
// Example startup helper for Kotlin N compiler. Compile to JAR and add it to
|
// Example startup helper for Kotlin/Native compiler. Compile to JAR and add it to
|
||||||
// Kotlin N classpath - it will get loaded and executed automatically.
|
// Kotlin/Native classpath - it will get loaded and executed automatically.
|
||||||
//
|
//
|
||||||
package org.jetbrains.kotlin.konan.util
|
package org.jetbrains.kotlin.konan.util
|
||||||
|
|
||||||
|
|||||||
Vendored
+3
-1
@@ -174,7 +174,9 @@ class HelperNativeDep extends TgzNativeDep {
|
|||||||
|
|
||||||
@TaskAction
|
@TaskAction
|
||||||
public void downloadAndExtract() {
|
public void downloadAndExtract() {
|
||||||
new DependencyProcessor(baseOutDir, konanProperties, [baseName], baseUrl).run()
|
def downloader = new DependencyProcessor(baseOutDir, konanProperties, [baseName], baseUrl)
|
||||||
|
downloader.showInfo = false
|
||||||
|
downloader.run()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -187,8 +187,11 @@ fun Path.recursiveCopyTo(destPath: Path) {
|
|||||||
|
|
||||||
// File systems don't allow replacing an existing root.
|
// File systems don't allow replacing an existing root.
|
||||||
if (newPath == newPath.getRoot()) return@next
|
if (newPath == newPath.getRoot()) return@next
|
||||||
Files.copy(oldPath, newPath,
|
if (Files.isDirectory(newPath)) {
|
||||||
StandardCopyOption.REPLACE_EXISTING)
|
Files.createDirectories(newPath)
|
||||||
|
} else {
|
||||||
|
Files.copy(oldPath, newPath, StandardCopyOption.REPLACE_EXISTING)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,15 +6,13 @@ import java.net.URL
|
|||||||
import java.net.URLConnection
|
import java.net.URLConnection
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.StandardCopyOption
|
import java.nio.file.StandardCopyOption
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.*
|
||||||
import java.util.concurrent.locks.ReentrantLock
|
|
||||||
import kotlin.concurrent.thread
|
|
||||||
import kotlin.concurrent.withLock
|
|
||||||
|
|
||||||
class DependencyDownloader(
|
class DependencyDownloader(
|
||||||
var maxAttempts: Int = DEFAULT_MAX_ATTEMPTS,
|
var maxAttempts: Int = DEFAULT_MAX_ATTEMPTS,
|
||||||
var attemptIntervalMs: Long = DEFAULT_ATTEMPT_INTERVAL_MS
|
var attemptIntervalMs: Long = DEFAULT_ATTEMPT_INTERVAL_MS
|
||||||
) {
|
) {
|
||||||
|
val executor = ExecutorCompletionService<Unit>(Executors.newSingleThreadExecutor())
|
||||||
|
|
||||||
enum class ReplacingMode {
|
enum class ReplacingMode {
|
||||||
/** Redownload the file and replace the existing one. */
|
/** Redownload the file and replace the existing one. */
|
||||||
@@ -25,41 +23,8 @@ class DependencyDownloader(
|
|||||||
RETURN_EXISTING
|
RETURN_EXISTING
|
||||||
}
|
}
|
||||||
|
|
||||||
class DownloadingProgress(@Volatile var currentBytes: Long, val totalBytes: Long) {
|
class DownloadingProgress(@Volatile var currentBytes: 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 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,
|
private fun doDownload(originalUrl: URL,
|
||||||
@@ -68,33 +33,40 @@ class DependencyDownloader(
|
|||||||
currentBytes: Long,
|
currentBytes: Long,
|
||||||
totalBytes: Long,
|
totalBytes: Long,
|
||||||
append: Boolean) {
|
append: Boolean) {
|
||||||
val progress = DownloadingProgress(currentBytes, totalBytes)
|
val progress = DownloadingProgress(currentBytes)
|
||||||
|
|
||||||
// TODO: Implement multi-thread downloading + use some sort of thread pool.
|
// TODO: Implement multi-thread downloading.
|
||||||
thread {
|
executor.submit {
|
||||||
Thread.setDefaultUncaughtExceptionHandler { _, throwable -> progress.done(throwable) }
|
|
||||||
connection.getInputStream().use { from ->
|
connection.getInputStream().use { from ->
|
||||||
FileOutputStream(tmpFile, append).use { to ->
|
FileOutputStream(tmpFile, append).use { to ->
|
||||||
val buffer = ByteArray(DEFAULT_BUFFER_SIZE)
|
val buffer = ByteArray(DEFAULT_BUFFER_SIZE)
|
||||||
var read = from.read(buffer)
|
var read = from.read(buffer)
|
||||||
while (read != -1) {
|
while (read != -1) {
|
||||||
|
if (Thread.interrupted()) {
|
||||||
|
throw InterruptedException()
|
||||||
|
}
|
||||||
to.write(buffer, 0, read)
|
to.write(buffer, 0, read)
|
||||||
progress.update(read)
|
progress.update(read)
|
||||||
read = from.read(buffer)
|
read = from.read(buffer)
|
||||||
}
|
}
|
||||||
if (currentBytes != totalBytes) {
|
if (progress.currentBytes != totalBytes) {
|
||||||
throw EOFException("The stream closed before end of downloading.")
|
throw EOFException("The stream closed before end of downloading.")
|
||||||
}
|
}
|
||||||
progress.done()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
progress.trackProgress(1000) {
|
var result: Future<Unit>?
|
||||||
updateProgressMsg(originalUrl.toString(), it.currentBytes, it.totalBytes)
|
do {
|
||||||
}
|
updateProgressMsg(originalUrl.toString(), progress.currentBytes, totalBytes)
|
||||||
if (!progress.doneCorrectly) {
|
result = executor.poll(1, TimeUnit.SECONDS)
|
||||||
throw progress.exception!!
|
} while(result == null)
|
||||||
|
updateProgressMsg(originalUrl.toString(), progress.currentBytes, totalBytes)
|
||||||
|
|
||||||
|
try {
|
||||||
|
result.get()
|
||||||
|
} catch (e: ExecutionException) {
|
||||||
|
throw e.cause ?: e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,6 +84,7 @@ class DependencyDownloader(
|
|||||||
connection.setRequestProperty("range", "bytes=$currentBytes-")
|
connection.setRequestProperty("range", "bytes=$currentBytes-")
|
||||||
connection.connect()
|
connection.connect()
|
||||||
} else {
|
} else {
|
||||||
|
currentBytes = 0
|
||||||
tmpFile.delete()
|
tmpFile.delete()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -148,10 +121,10 @@ class DependencyDownloader(
|
|||||||
replace: ReplacingMode = ReplacingMode.RETURN_EXISTING): File {
|
replace: ReplacingMode = ReplacingMode.RETURN_EXISTING): File {
|
||||||
|
|
||||||
if (destination.exists()) {
|
if (destination.exists()) {
|
||||||
@Suppress("NON_EXHAUSTIVE_WHEN")
|
|
||||||
when (replace) {
|
when (replace) {
|
||||||
ReplacingMode.RETURN_EXISTING -> return destination
|
ReplacingMode.RETURN_EXISTING -> return destination
|
||||||
ReplacingMode.THROW -> throw FileAlreadyExistsException(destination)
|
ReplacingMode.THROW -> throw FileAlreadyExistsException(destination)
|
||||||
|
ReplacingMode.REPLACE -> Unit // Just continue with downloading.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val tmpFile = File("${destination.canonicalPath}.$TMP_SUFFIX")
|
val tmpFile = File("${destination.canonicalPath}.$TMP_SUFFIX")
|
||||||
@@ -160,7 +133,7 @@ class DependencyDownloader(
|
|||||||
"A temporary file is a directory: ${tmpFile.canonicalPath}. Remove it and try again."
|
"A temporary file is a directory: ${tmpFile.canonicalPath}. Remove it and try again."
|
||||||
}
|
}
|
||||||
check(!destination.isDirectory) {
|
check(!destination.isDirectory) {
|
||||||
"The destination file is a directory: ${tmpFile.canonicalPath}. Remove it and try again."
|
"The destination file is a directory: ${destination.canonicalPath}. Remove it and try again."
|
||||||
}
|
}
|
||||||
|
|
||||||
var attempt = 1
|
var attempt = 1
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ class DependencyProcessor(dependenciesRoot: File,
|
|||||||
|
|
||||||
val lockFile = File(cacheDirectory, ".lock").apply { if (!exists()) createNewFile() }
|
val lockFile = File(cacheDirectory, ".lock").apply { if (!exists()) createNewFile() }
|
||||||
|
|
||||||
|
var showInfo = true
|
||||||
private var isInfoShown = false
|
private var isInfoShown = false
|
||||||
|
|
||||||
// TOOO: Rename pause -> interval
|
// TOOO: Rename pause -> interval
|
||||||
@@ -135,7 +136,7 @@ class DependencyProcessor(dependenciesRoot: File,
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isInfoShown) {
|
if (showInfo && !isInfoShown) {
|
||||||
println("Downloading native dependencies (LLVM, sysroot etc). This is a one-time action performed only on the first run of the compiler.")
|
println("Downloading native dependencies (LLVM, sysroot etc). This is a one-time action performed only on the first run of the compiler.")
|
||||||
isInfoShown = true
|
isInfoShown = true
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user