Должен подойти такой вариант
func start() {
file, _ := os.ReadFile("./data.txt")
for _, i := range strings.Split(string(file), "\n") {
select {
case <-stop:
return
default:
http.Get(Url + i)
}
}
}
На каждой итерации цикла проверяем, было ли сообщение в канал, если не было, обрабатываем очередной урл. Минус в том, что проверяем мы только между обработками урлов. Если обработка одного урла это пара секунд, то все норм.
Более сложный вариант
package main
import (
"context"
"errors"
"io/ioutil"
"net/http"
"strings"
)
func start() {
file, _ := os.ReadFile("./data.txt")
ctx, cancel := context.WithCancel(context.Background())
defer cancel() // контекст обязательно надо отменять в конце
go func() {
select {
// Отменяем контекст при получении стоп-сигнала
case <-stop:
cancel()
// чтобы горутина завершилась по отмене контекста даже если stop не будет
case <-ctx.Done():
}
}()
for _, i := range strings.Split(string(file), "\n") {
err := processUrl(ctx, Url+i)
if err != nil {
if errors.Is(err, context.Canceled) {
return
}
// обработать ошибку
}
}
}
func processUrl(ctx context.Context, finalUrl string) error {
req, err := http.NewRequestWithContext(ctx, "GET", finalUrl, nil)
if err != nil {
return err
}
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close() // обязательно, иначе будет утечка
// обработать ответ
return nil
}
Здесь уже выход будет мгновенный, потому что http-запрос отменится по контексту хоть на середине.