Webcrawler в Go

Я пытаюсь создать веб-сканер в Go, где я хотел бы указать максимальное количество одновременных работников. Все они будут работать до тех пор, пока в очереди есть ссылки для исследования. Когда в очереди меньше элементов, чем у рабочих, рабочие должны кричать, но возобновить работу, если будет найдено больше ссылок.

Код, который я пробовал

const max_workers = 6
// simulating links with int
func crawl(wg *sync.WaitGroup, queue chan int) {
    for element := range queue {   
        wg.Done() // why is defer here causing a deadlock?
        fmt.Println("adding 2 new elements ")
        if element%2 == 0 {
            wg.Add(2)
            queue <- (element*100 + 11)
            queue <- (element*100 + 33)
        }

    }
}

func main() {
    var wg sync.WaitGroup
    queue := make(chan int, 10)
    queue <- 0
    queue <- 1
    queue <- 2
    queue <- 3
    var min int
    if (len(queue) < max_workers) {
        min = len(queue)
    } else {
        min = max_workers
    }
    for i := 0; i < min; i++ {
        wg.Add(1)
        go crawl(&wg, queue)
    }
    wg.Wait()
    close(queue)
}

Ссылка на игровую площадку

Кажется, это работает, но есть одна загвоздка: мне нужно заполнить очередь несколькими элементами при запуске. Я хотел бы, чтобы это началось со (единственной) начальной страницы (в моем примереqueue <- 0), а затем динамически увеличивать / уменьшать рабочий пул.

Мои вопросы:

как я могу получить поведение?

почему отложеноwg.Done() вызывая тупик? Это нормальноwg.Done() функция, когда она на самом деле завершена? Я думаю, что безdefer программа не ждет завершения другой части (что может занять больше времени в реальном примере анализа HTML).

Ответы на вопрос(1)

Ваш ответ на вопрос