From dfe21445e551148d8c2763cf07983a9ab838b5ee Mon Sep 17 00:00:00 2001 From: Joren Date: Fri, 13 Sep 2024 22:17:16 +0200 Subject: [PATCH] Kill downloader process to instantly abort --- downloaders.go | 27 ++++++++++++++++++++++++--- go.mod | 1 + go.sum | 2 ++ main.go | 8 ++++++-- utils.go | 18 +++++++++++++----- 5 files changed, 46 insertions(+), 10 deletions(-) diff --git a/downloaders.go b/downloaders.go index 4816773..67d615c 100644 --- a/downloaders.go +++ b/downloaders.go @@ -18,7 +18,7 @@ func removeBOM(input []byte) []byte { return input } -func downloadFile(item Item) error { +func downloadFile(item Item, jobInfo *JobInfo) error { fmt.Println("Downloading:", item.Filename) mpdPath := item.MPD @@ -91,12 +91,33 @@ func downloadFile(item Item) error { cmd := exec.Command("bash", "-c", command) + jobsMutex.Lock() + jobInfo.Cmd = cmd + jobsMutex.Unlock() + cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr - err := cmd.Run() + err := cmd.Start() if err != nil { - return fmt.Errorf("error executing download command: %v", err) + return fmt.Errorf("error starting download command: %v", err) + } + + done := make(chan error) + go func() { + done <- cmd.Wait() + }() + + select { + case <-jobInfo.AbortChan: + if cmd.Process != nil { + cmd.Process.Kill() + } + return fmt.Errorf("download aborted") + case err := <-done: + if err != nil { + return fmt.Errorf("error executing download command: %v", err) + } } fmt.Println("Download completed successfully") diff --git a/go.mod b/go.mod index bc9873f..7614d61 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,7 @@ require ( require ( github.com/asticode/go-astikit v0.20.0 // indirect github.com/asticode/go-astits v1.8.0 // indirect + github.com/pkg/exec v0.0.0-20150614095509-0bd164ad2a5a golang.org/x/net v0.0.0-20200904194848-62affa334b73 // indirect golang.org/x/text v0.3.2 // indirect ) diff --git a/go.sum b/go.sum index 92cc1b6..97fe73a 100644 --- a/go.sum +++ b/go.sum @@ -10,6 +10,8 @@ github.com/beevik/etree v1.4.1 h1:PmQJDDYahBGNKDcpdX8uPy1xRCwoCGVUiW669MEirVI= github.com/beevik/etree v1.4.1/go.mod h1:gPNJNaBGVZ9AwsidazFZyygnd+0pAU38N4D+WemwKNs= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pkg/exec v0.0.0-20150614095509-0bd164ad2a5a h1:EN123kAtAAE2pg/+TvBsUBZfHCWNNFyL2ZBPPfNWAc0= +github.com/pkg/exec v0.0.0-20150614095509-0bd164ad2a5a/go.mod h1:b95YoNrAnScjaWG+asr8lxqlrsPUcT2ZEBcjvVGshMo= github.com/pkg/profile v1.4.0/go.mod h1:NWz/XGvpEW1FyYQ7fCx4dqYBLlfTcE+A9FLAkNKqjFE= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= diff --git a/main.go b/main.go index 3eb5277..fe74b32 100644 --- a/main.go +++ b/main.go @@ -124,7 +124,7 @@ func handleAbort(w http.ResponseWriter, r *http.Request) { } jobsMutex.Lock() - abortChan, exists := jobs[filename] + jobInfo, exists := jobs[filename] jobsMutex.Unlock() if !exists { @@ -132,6 +132,10 @@ func handleAbort(w http.ResponseWriter, r *http.Request) { return } - close(abortChan) + close(jobInfo.AbortChan) + if jobInfo.Cmd != nil && jobInfo.Cmd.Process != nil { + jobInfo.Cmd.Process.Kill() + } + fmt.Fprintf(w, "Abort signal sent for %s", filename) } diff --git a/utils.go b/utils.go index 5c3c758..62d6ed7 100644 --- a/utils.go +++ b/utils.go @@ -6,6 +6,7 @@ import ( "io" "net/url" "os" + "os/exec" "regexp" "strconv" "strings" @@ -14,9 +15,14 @@ import ( "github.com/beevik/etree" ) +type JobInfo struct { + AbortChan chan struct{} + Cmd *exec.Cmd +} + var ( jobsMutex sync.Mutex - jobs = make(map[string]chan struct{}) + jobs = make(map[string]*JobInfo) ) func sanitizeFilename(filename string) string { @@ -180,8 +186,10 @@ func filterSelectedItems(items []Item, selectedItems []string) []Item { func processItems(filename string, items []Item) error { jobsMutex.Lock() - abortChan := make(chan struct{}) - jobs[filename] = abortChan + jobInfo := &JobInfo{ + AbortChan: make(chan struct{}), + } + jobs[filename] = jobInfo jobsMutex.Unlock() defer func() { @@ -192,12 +200,12 @@ func processItems(filename string, items []Item) error { for i, item := range items { select { - case <-abortChan: + case <-jobInfo.AbortChan: updateProgress(filename, 100, "Aborted") return fmt.Errorf("download aborted") default: updateProgress(filename, float64(i)/float64(len(items))*100, item.Filename) - err := downloadFile(item) + err := downloadFile(item, jobInfo) if err != nil { fmt.Printf("Error downloading file: %v\n", err) }