Golang: Как остановить загрузку большого файла
Есть функция DownloadByLink() которая выполняется условно 10 мин(загрузка файла). Как прервать выполнение функции DownloadByLink по требованию, из другой функции?
Функция которую нужно прорвать
// DownloadByLink ...
func (r bigfileRepository) DownloadByLink(bf *model.Bigfile) error {
resp, err := http.Get(bf.Link)
if err != nil {
return err
}
if resp.StatusCode != http.StatusOK {
zap.L().Error(fmt.Sprintf("error download file by link. code: %d status: %s", resp.StatusCode, resp.Status), zap.Error(err))
return err
}
zap.L().Info("file download beginning",
zap.String("name", bf.Name),
zap.String("uuid", fmt.Sprintln(bf.Uuid)),
zap.String("link", bf.Link),
)
defer resp.Body.Close()
bytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
bf.FileBytes = bytes
bf.Size = len(bytes)
zap.L().Info("file download complete",
zap.String("name", bf.Name),
zap.String("uuid", fmt.Sprintln(bf.Uuid)),
zap.String("size", fmt.Sprintln(bf.Size)),
zap.String("link", bf.Link),
)
return nil
}
Ответы (1 шт):
Автор решения: Pak Uula
→ Ссылка
Вам нужно прикрепить к запросу контекст с заданным дедлайном. Http клиент в go умеет отслеживать истечение дедлайна и завершать запрос.
Вот пример:
package main
import (
"context"
"errors"
"log"
"net/http"
"time"
)
func main() {
ctx := context.Background()
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
// Request with 20 seconds delay
req, err := http.NewRequestWithContext(ctx, "GET", "http://httpbin.org/delay/20", nil)
if err != nil {
log.Fatalf("%v", err)
return
}
defer cancel() // Cleanup resources
client := http.DefaultClient
resp, err := client.Do(req) // Execute the request
if err != nil {
if errors.Is(errors.Unwrap(err), context.DeadlineExceeded) {
log.Fatal("Request failed: Context deadline exceeded")
} else {
log.Fatalf("Request failed: %#v", err)
}
} else {
log.Printf("Request executed: %v\n", resp.StatusCode)
}
}