fix: stabler ETA for uploads
Massimo Melina committed
Jul 18, 2025 at 22:53 UTC
ed5738dd52b3c81d800a16d34a5b98d052fd0b32
2 files changed
+10
-3
frontend/src/upload.ts
+1
-1
@@ -48,7 +48,7 @@ export function showUpload() {
48
function Content(){
49
const { qs, paused, eta, speed, adding } = useSnapshot(uploadState) as Readonly<typeof uploadState>
50
const { props, uploadOnExisting } = useSnapState()
51
- const etaStr = useMemo(() => !eta ? '' : formatTime(eta*1000, 0, 2), [eta])
51
+ const etaStr = useMemo(() => !eta || eta === Infinity ? '' : formatTime(eta*1000, 0, 2), [eta])
52
const inQ = _.sumBy(qs, q => q.entries.length) - (uploadState.uploading ? 1 : 0)
53
const queueStr = inQ && t('in_queue', { n: inQ }, "{n} in queue")
54
const size = formatBytes(adding.reduce((a, x) => a + x.file.size, 0))
frontend/src/uploadQueue.ts
+9
-2
@@ -54,10 +54,11 @@ let stuckSince = Infinity
54
// keep track of speed
55
let bytesSentTimestamp = Date.now()
56
let bytesSent = 0
57
+const recentSpeedSamples: number[] = []
58
setInterval(() => {
59
const now = Date.now()
60
const passed = (now - bytesSentTimestamp) / 1000
60
- uploadState.speed = bytesSent / passed
61
+ const speed = bytesSent / passed
62
if (currentReq && now - stuckSince >= 10_000) { // this will normally cause the upload to be retried after long time of no progress
63
currentReq.abort()
64
console.debug('upload stuck, aborting')
@@ -68,7 +69,13 @@ setInterval(() => {
69
// keep track of ETA
70
const qBytes = _.sumBy(uploadState.qs, q => _.sumBy(q.entries, x => x.file.size))
71
const left = (qBytes - uploadState.partial)
71
- uploadState.eta = uploadState.speed && Math.round(left / uploadState.speed)
72
+ const doSample = uploadState.uploading
73
+ if (doSample)
74
+ recentSpeedSamples.push(speed)
75
+ if (!doSample || recentSpeedSamples.length > 5) // max 5 samples, 10 seconds
76
+ recentSpeedSamples.shift()
77
+ uploadState.speed = _.mean(recentSpeedSamples)
78
+ uploadState.eta = left / uploadState.speed
79
}, 2_000)
80
81
let currentReq: XMLHttpRequest | undefined