Stop speed tracker immediately if download is done

Subsequent disk I/O will make the reported download speed inaccurate.
This commit is contained in:
FooIbar committed 2025-08-14 19:25:03 +08:00
1 parent 8c27504ee2
commit d5abbb3584
2 files changed
+15 -13

No files matched your search

@@ -711,9 +711,7 @@ object DownloadManager : OnSpiderListener, CoroutineScope {
fun start() {
if (currentJob == null) {
currentJob = launch {
tracker.speedFlow().collect { speed ->
updateSpeed(speed.toLong())
}
tracker.speedFlow().collect(::updateSpeed)
}
}
}
@@ -24,7 +24,7 @@ import kotlin.time.Duration.Companion.seconds
import kotlin.time.Instant
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
@@ -47,7 +47,7 @@ class SpeedTracker(val window: Duration = 1.seconds) {
}
}
fun speedFlow(sample: Duration = 1.seconds) = fixedRate(sample).map {
fun speedFlow(sample: Duration = 1.seconds) = fixedRate(sample).mapNotNull {
mutex.withLock {
start?.let { start ->
val now = Clock.System.now()
@@ -55,8 +55,8 @@ class SpeedTracker(val window: Duration = 1.seconds) {
val window = passed.coerceIn(10.milliseconds, window)
val cutoff = now - window
received.removeIf { time, _ -> time < cutoff }
received.fold(0) { total, _, v -> total + v } / (window / 1.seconds)
} ?: 0.0
(received.fold(0) { total, _, v -> total + v } / (window / 1.seconds)).toLong()
}
}
}
}
@@ -80,8 +80,12 @@ suspend inline fun <R> timeoutBySpeed(
var prev = 0L
onDownload { done, total ->
val bytesRead = (done - prev).toInt()
tracker.track(bytesRead)
l(total!!, done, bytesRead)
if (done == total!!) {
tracker.reset()
} else {
tracker.track(bytesRead)
}
l(total, done, bytesRead)
prev = done
}
timeout { reset() }
@@ -89,10 +93,10 @@ suspend inline fun <R> timeoutBySpeed(
watchdog.cancel()
resp.status.ensureSuccess()
val speedWatchdog = launch {
val timeoutSpeed = speedLevelToSpeed(Settings.timeoutSpeed.value) * 1024.0
tracker.speedFlow(1.seconds).collect { speed ->
if (timeoutSpeed != 0.0 && speed < timeoutSpeed) {
onTimeout(LowSpeedException(url, speed.toLong()))
val timeoutSpeed = speedLevelToSpeed(Settings.timeoutSpeed.value) * 1024L
tracker.speedFlow().collect { speed ->
if (speed < timeoutSpeed) {
onTimeout(LowSpeedException(url, speed))
}
}
}