fix: show first progress update immediately instead of waiting for 5%
- Always show the first nonzero progress update so users don't see 0% for extended periods on slow downloads or fragment-based downloads - Keep 5% throttle for subsequent updates to avoid excessive API calls - Add readProgress summary logging (lines, matches, stderr length) - Fix progressKeyboard not being updated until progress >= 5%
This commit is contained in:
@@ -3,6 +3,7 @@ package dl
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"io"
|
"io"
|
||||||
|
"log/slog"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -60,8 +61,11 @@ func parseProgressLine(line string) *progressUpdate {
|
|||||||
func readProgress(stderr io.ReadCloser, updates chan<- *domain.DownloadJob, job *domain.DownloadJob) {
|
func readProgress(stderr io.ReadCloser, updates chan<- *domain.DownloadJob, job *domain.DownloadJob) {
|
||||||
var stderrBuf strings.Builder
|
var stderrBuf strings.Builder
|
||||||
scanner := bufio.NewScanner(stderr)
|
scanner := bufio.NewScanner(stderr)
|
||||||
|
lineCount := 0
|
||||||
|
matchCount := 0
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
line := scanner.Text()
|
line := scanner.Text()
|
||||||
|
lineCount++
|
||||||
|
|
||||||
if stderrBuf.Len() < 4096 {
|
if stderrBuf.Len() < 4096 {
|
||||||
stderrBuf.WriteString(line)
|
stderrBuf.WriteString(line)
|
||||||
@@ -72,10 +76,12 @@ func readProgress(stderr io.ReadCloser, updates chan<- *domain.DownloadJob, job
|
|||||||
if parsed == nil {
|
if parsed == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
matchCount++
|
||||||
job.Progress = parsed.pct
|
job.Progress = parsed.pct
|
||||||
job.Speed = parsed.speed
|
job.Speed = parsed.speed
|
||||||
job.ETA = parsed.eta
|
job.ETA = parsed.eta
|
||||||
updates <- job
|
updates <- job
|
||||||
}
|
}
|
||||||
job.StderrLog = stderrBuf.String()
|
job.StderrLog = stderrBuf.String()
|
||||||
|
slog.Info("readProgress finished", "url", job.URL, "lines", lineCount, "matches", matchCount, "stderr_len", len(job.StderrLog))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -396,6 +396,8 @@ func (h *Handler) runDownload(ctx context.Context, job *domain.DownloadJob) {
|
|||||||
|
|
||||||
lastProgress := 0.0
|
lastProgress := 0.0
|
||||||
for upd := range updates {
|
for upd := range updates {
|
||||||
|
slog.Info("progress update", "pct", upd.Progress, "speed", upd.Speed, "status", upd.Status)
|
||||||
|
|
||||||
h.mu.Lock()
|
h.mu.Lock()
|
||||||
currentJob := h.activeJobs[job.UserID]
|
currentJob := h.activeJobs[job.UserID]
|
||||||
h.mu.Unlock()
|
h.mu.Unlock()
|
||||||
@@ -419,18 +421,23 @@ func (h *Handler) runDownload(ctx context.Context, job *domain.DownloadJob) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if upd.Progress-lastProgress >= domain.ProgressThreshold || upd.Status == domain.StatusCompleted {
|
// Always show the first real progress update, then throttle at 5% intervals
|
||||||
|
if upd.Progress > 0 && lastProgress == 0 {
|
||||||
|
lastProgress = upd.Progress
|
||||||
|
} else if upd.Progress-lastProgress < domain.ProgressThreshold && upd.Status != domain.StatusCompleted {
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
lastProgress = upd.Progress
|
lastProgress = upd.Progress
|
||||||
|
|
||||||
if upd.Progress > domain.QuotaProgressThreshold && !job.QuotaApplied && job.FileSize > 0 {
|
|
||||||
job.QuotaApplied = true
|
|
||||||
h.applyQuota(job.UserID, job.FileSize)
|
|
||||||
}
|
|
||||||
|
|
||||||
kb := progressKeyboard(upd.Progress, upd.Speed, upd.ETA)
|
|
||||||
text := fmt.Sprintf("Downloading: %s", job.Title)
|
|
||||||
h.editText(ctx, job.ChatID, job.MessageID, text, &kb)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if upd.Progress > domain.QuotaProgressThreshold && !job.QuotaApplied && job.FileSize > 0 {
|
||||||
|
job.QuotaApplied = true
|
||||||
|
h.applyQuota(job.UserID, job.FileSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
kb := progressKeyboard(upd.Progress, upd.Speed, upd.ETA)
|
||||||
|
text := fmt.Sprintf("Downloading: %s", job.Title)
|
||||||
|
h.editText(ctx, job.ChatID, job.MessageID, text, &kb)
|
||||||
}
|
}
|
||||||
|
|
||||||
h.mu.Lock()
|
h.mu.Lock()
|
||||||
|
|||||||
Reference in New Issue
Block a user