refactor: split mutex, add download queue, wire context cancellation
All checks were successful
CI / build (push) Successful in 53s
All checks were successful
CI / build (push) Successful in 53s
- Split single sync.Mutex into per-map mutexes (activeJobs, stepStates, rateLimiter, pendingInput, cancelFuncs) to reduce contention - Add download semaphore (channel-buffered, 3 concurrent) as worker pool - Add cancelFuncs map with context cancellation wired into download goroutines for clean shutdown - Replace playlist busy-poll (500ms sleep loop) with synchronous runDownload + Done channel for completion tracking - Use full UUID for job IDs instead of 8-char prefix - Download thumbnail URL to temp file before sending (InputFileUpload) - Change MAX_FILE_SIZE_MB default from 2000 to 50 - Clean up cancel funcs after normal download completion
This commit is contained in:
@@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"uptodownBot/internal/domain"
|
||||
)
|
||||
@@ -164,6 +163,8 @@ func (h *Handler) handlePlaylistConfirm(ctx context.Context, chatID int64, msgID
|
||||
}
|
||||
}
|
||||
|
||||
dlCtx, dlCancel := context.WithCancel(context.Background())
|
||||
|
||||
job := &domain.DownloadJob{
|
||||
ID: h.generateJobID(),
|
||||
UserID: userID,
|
||||
@@ -176,19 +177,17 @@ func (h *Handler) handlePlaylistConfirm(ctx context.Context, chatID int64, msgID
|
||||
Status: domain.StatusDownloading,
|
||||
Title: entry.Title,
|
||||
FileSize: format.Filesize,
|
||||
Done: make(chan struct{}),
|
||||
}
|
||||
|
||||
h.setActiveJob(userID, job)
|
||||
h.runDownload(context.Background(), job)
|
||||
h.setCancelFunc(userID, dlCancel)
|
||||
|
||||
// Wait for active job to complete
|
||||
for {
|
||||
j := h.getActiveJob(userID)
|
||||
if j == nil || j.Status == domain.StatusCompleted || j.Status == domain.StatusFailed || j.Status == domain.StatusCancelled {
|
||||
break
|
||||
}
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
}
|
||||
h.runDownload(dlCtx, job)
|
||||
|
||||
// runDownload is synchronous — it blocks until the download completes.
|
||||
// The Done channel is closed inside runDownload when it exits.
|
||||
// No busy-polling needed.
|
||||
}
|
||||
|
||||
h.sendText(ctx, chatID, "All playlist downloads completed.")
|
||||
|
||||
Reference in New Issue
Block a user